Streamwriter only writes a certain amount of bytes from a string list

爷,独闯天下 提交于 2021-02-10 13:15:54

问题


I have 27 csv files containing employee timesheet data with about 2000 lines of data in total, and is growing day by day.

I am writing an application that compiles the data in each file to a single csv file for analysis in Excel. I do this by reading each file, write its contents to a string list and then write the string list to a new file. Below is the code writing the list to the file:

FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
foreach (string l in reader)//reader is a List<string> pouplated earlier
{
    sw.WriteLine(l);
}
fs.Close();

reader is a list containing about 1170 lines of timesheet entries. When I query the contentents of reader all of the data is present.

The problem comes when I open the compiled csv, all of the data is present except for the last few lines of the last timesheet file. The compiled file contains only 1167 full lines with line 1168 cut off at some arbitrary point. After scrutinizing different files with different contents I noticed that each file is exactly 160840bytes in size.

For debugging purposes I modified the code like this:

string line = "";//A string to test whether the foreach loop completes
FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
foreach (string l in reader)//reader is a List<string> pouplated earlier
{
    line = l;
    sw.WriteLine(line);
    sw.WriteLine("testline")//write random content to see if it has effect on the data
}
fs.Close();
MessageBox.Show(line);

With this modification the message that pops up after the code is run displays the correct entry that should have been written to the file (but is not); this is evidence that the foreach loop loops through all the data. The compiled file now has a larger size of around 200kB. When I scrutinize it, all of the "testline" lines are added, the actual timesheet entry is still cut off at the same arbitrary point as when the "testline" lines were not written.

In summary:

  • I'm trying write a string list to a file
  • All of the necessary data is present in the list
  • The code loops through all of the data in the list
  • The final written file does not contain all of the data in the list

Can anyone advise me on what is going wrong? I will try a different approach to write the contents to the file, but I would still like to know what happens here and what I can do to prevent it.


回答1:


The StreamWriter class has its own buffer, if you don't dispose/close it, the rest of the buffer will be lost, exactly as you've observed.

There are multiple ways to flush this buffer.

You could explicitly flush it:

sw.Flush();

but that's not the advice I would want to give, instead you should dispose of the StreamWriter instance which will also flush the buffer to the underlying stream, and as a general guideline, any object that implements IDisposable should be disposed of when you're done with it.

So modify your code like this:

using (FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite))
using (StreamWriter sw = new StreamWriter(fs))
{
    foreach (string l in reader)//reader is a List<string> pouplated earlier
    {
        sw.WriteLine(l);
    }
}

If you want to dig deeper into how the StreamWriter class works I suggest examining the Reference Source Code of StreamWriter.



来源:https://stackoverflow.com/questions/32068969/streamwriter-only-writes-a-certain-amount-of-bytes-from-a-string-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!