M
Marty McDonald
Sometimes I use FileMode.OpenOrCreate to write data to a file. Then, when I
try to write to that file again, remanants of the first set of data exist in
the file.
I'd understand if it was trying to append or something, but when only part
of the first set of data exists, I think it's an error. If anyone has any
information on this, it would be good... For now I will just warn the users
of this class, so no resolution is necessary...
Thanks!
Code follows for those interested...
using System;
using System.Data;
using System.IO;
namespace WSDOT.Spectrum
{
/// <summary>
/// Will write data to a file, delimiting each field by a specified
delimiter.
/// </summary>
/// <remarks>Certain characters may adversely affect results. For example,
if
/// the chosen delimiter is a semi-colon, existing semi-colons in the data
itself may cause problems for
/// those applications that consume the resultant file.
/// <p>Newline characters in the data itself may cause a line break where
one might not be wanted.
/// </p>
/// <p>If the data contains columns of special data types (such as 'image'),
the string 'System.Byte[]'
/// will be written in place of the actual value.
/// </p>
/// <p>Use FileMode.OpenOrCreate with caution - its behavior is
unpredictable
/// when used against a file that already contains data.
/// </p>
/// <p>It is the programmer's responsibility to anticipate and respond to
such situations.
/// </p>
/// </remarks>
public class DelimitedWriter
{
/// <summary>
/// Constructor is private so class cannot be instantiated.
/// </summary>
private DelimitedWriter()
{
}
/// <summary>
/// Will persist given DataTable to a delimited file.
/// </summary>
/// <param name="dataTable">DataTable containing data to write.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - its behavior is unpredictable
when used against a file that already contains data.</param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataTable dataTable,string fileName,
FileMode mode, Char delimiter, bool includeColumnHeadings)
{
FileStream fs = new FileStream(fileName,mode,FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
//The "seek" method fixes an issue which is...
//If a file is created with
string line = "";
//Write the column headings if desired.
if (includeColumnHeadings)
{
for (Int32 i = 0; i < dataTable.Columns.Count; i++)
{
line += dataTable.Columns.ColumnName + delimiter;
}
sw.WriteLine(line);
line = "";
}
//Now write the actual values.
for (Int32 i = 0; i < dataTable.Rows.Count; i++) //loop through each row
{
for (Int32 z = 0; z < dataTable.Columns.Count; z++) //loop throuch each
column
{
line += dataTable.Rows[z].ToString() + delimiter;
}
sw.WriteLine(line);
line = "";
}
sw.Close();
fs.Close();
return true;
}
/// <summary>
/// Will persist first table in a DataSet to a delimited file.
/// </summary>
/// <param name="dataSet">DataSet containing data to persist.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - its behavior is unpredictable
when used
/// against a file that already contains data.
/// </param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataSet dataSet, string fileName,
FileMode mode, Char delimiter, bool includeColumnHeadings)
{
return
CreateDelimitedFile(dataSet.Tables[0],fileName,mode,delimiter,includeColumnH
eadings);
}
/// <summary>
/// Will persist ordinally-numbered table in a DataSet to a delimited file.
/// </summary>
/// <param name="dataSet">DataSet containing data to persist.</param>
/// <param name="whichTable">Ordinal table number to persist.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - it's behavior is unpredictable
when used
/// against a file that already contains data.
/// </param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataSet dataSet,Int32 whichTable,
string fileName, FileMode mode, Char delimiter, bool includeColumnHeadings)
{
return
CreateDelimitedFile(dataSet.Tables[whichTable],fileName,mode,delimiter,inclu
deColumnHeadings);
}
/// <summary>
/// Will persist named table in a DataSet to a delimited file.
/// </summary>
/// <param name="dataSet">DataSet containing data to persist.</param>
/// <param name="whichTable">Named table to persist.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - it's behavior is unpredictable
when used
/// against a file that already contains data.
/// </param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataSet dataSet,string whichTable,
string fileName, FileMode mode, Char delimiter, bool includeColumnHeadings)
{
return
CreateDelimitedFile(dataSet.Tables[whichTable],fileName,mode,delimiter,inclu
deColumnHeadings);
}
}//end class
}
try to write to that file again, remanants of the first set of data exist in
the file.
I'd understand if it was trying to append or something, but when only part
of the first set of data exists, I think it's an error. If anyone has any
information on this, it would be good... For now I will just warn the users
of this class, so no resolution is necessary...
Thanks!
Code follows for those interested...
using System;
using System.Data;
using System.IO;
namespace WSDOT.Spectrum
{
/// <summary>
/// Will write data to a file, delimiting each field by a specified
delimiter.
/// </summary>
/// <remarks>Certain characters may adversely affect results. For example,
if
/// the chosen delimiter is a semi-colon, existing semi-colons in the data
itself may cause problems for
/// those applications that consume the resultant file.
/// <p>Newline characters in the data itself may cause a line break where
one might not be wanted.
/// </p>
/// <p>If the data contains columns of special data types (such as 'image'),
the string 'System.Byte[]'
/// will be written in place of the actual value.
/// </p>
/// <p>Use FileMode.OpenOrCreate with caution - its behavior is
unpredictable
/// when used against a file that already contains data.
/// </p>
/// <p>It is the programmer's responsibility to anticipate and respond to
such situations.
/// </p>
/// </remarks>
public class DelimitedWriter
{
/// <summary>
/// Constructor is private so class cannot be instantiated.
/// </summary>
private DelimitedWriter()
{
}
/// <summary>
/// Will persist given DataTable to a delimited file.
/// </summary>
/// <param name="dataTable">DataTable containing data to write.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - its behavior is unpredictable
when used against a file that already contains data.</param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataTable dataTable,string fileName,
FileMode mode, Char delimiter, bool includeColumnHeadings)
{
FileStream fs = new FileStream(fileName,mode,FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
//The "seek" method fixes an issue which is...
//If a file is created with
string line = "";
//Write the column headings if desired.
if (includeColumnHeadings)
{
for (Int32 i = 0; i < dataTable.Columns.Count; i++)
{
line += dataTable.Columns.ColumnName + delimiter;
}
sw.WriteLine(line);
line = "";
}
//Now write the actual values.
for (Int32 i = 0; i < dataTable.Rows.Count; i++) //loop through each row
{
for (Int32 z = 0; z < dataTable.Columns.Count; z++) //loop throuch each
column
{
line += dataTable.Rows[z].ToString() + delimiter;
}
sw.WriteLine(line);
line = "";
}
sw.Close();
fs.Close();
return true;
}
/// <summary>
/// Will persist first table in a DataSet to a delimited file.
/// </summary>
/// <param name="dataSet">DataSet containing data to persist.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - its behavior is unpredictable
when used
/// against a file that already contains data.
/// </param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataSet dataSet, string fileName,
FileMode mode, Char delimiter, bool includeColumnHeadings)
{
return
CreateDelimitedFile(dataSet.Tables[0],fileName,mode,delimiter,includeColumnH
eadings);
}
/// <summary>
/// Will persist ordinally-numbered table in a DataSet to a delimited file.
/// </summary>
/// <param name="dataSet">DataSet containing data to persist.</param>
/// <param name="whichTable">Ordinal table number to persist.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - it's behavior is unpredictable
when used
/// against a file that already contains data.
/// </param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataSet dataSet,Int32 whichTable,
string fileName, FileMode mode, Char delimiter, bool includeColumnHeadings)
{
return
CreateDelimitedFile(dataSet.Tables[whichTable],fileName,mode,delimiter,inclu
deColumnHeadings);
}
/// <summary>
/// Will persist named table in a DataSet to a delimited file.
/// </summary>
/// <param name="dataSet">DataSet containing data to persist.</param>
/// <param name="whichTable">Named table to persist.</param>
/// <param name="fileName">File to write to.</param>
/// <param name="mode">Specifies how the operating system should write to
the file.
/// Use FileMode.OpenOrCreate with caution - it's behavior is unpredictable
when used
/// against a file that already contains data.
/// </param>
/// <param name="delimiter">Delimiter to use.</param>
/// <param name="includeColumnHeadings">If true, will include column
headings.</param>
/// <returns>True if successful.</returns>
public static bool CreateDelimitedFile(DataSet dataSet,string whichTable,
string fileName, FileMode mode, Char delimiter, bool includeColumnHeadings)
{
return
CreateDelimitedFile(dataSet.Tables[whichTable],fileName,mode,delimiter,inclu
deColumnHeadings);
}
}//end class
}