2015-08-18 2 views
2

У меня есть 27 файлов csv, содержащих данные о расписании сотрудников с примерно 2000 строками данных, и растет с каждым днем.Streamwriter записывает только определенное количество байтов из списка строк

Я пишу приложение, которое компилирует данные в каждом файле в один файл csv для анализа в Excel. Я делаю это, читая каждый файл, записывая его содержимое в строковый список, а затем записывая список строк в новый файл. Ниже приведен код записи списка в файл:

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 является список, содержащий около 1170 строк записей расписаний. Когда я запрашиваю контент reader, все данные присутствуют.

Проблема возникает, когда я открываю скомпилированный csv, все данные присутствуют, за исключением последних нескольких строк последнего файла расписания. Скомпилированный файл содержит только 1167 полных строк с отключенной строкой 1168 в некоторой произвольной точке. После тщательного анализа разных файлов с различным содержимым я заметил, что каждый файл имеет размер 160840 байтов.

Для целей отладки я изменил код так:

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); 

С этой модификацией сообщений, которое появляется после того, как код запуск отображает правильную запись, которая должна была быть записана в файл (но не является); это свидетельствует о том, что цикл foreach проходит через все данные. Скомпилированный файл теперь имеет размер более 200 КБ. Когда я его тщательно изучаю, все строки "testline" добавляются, фактическая запись в расписании все еще прерывается в той же произвольной точке, что и в случае, когда строки "testline" не были записаны.

В итоге:

  • Я пытаюсь написать список строк в файл
  • Все необходимые данные присутствуют в списке
  • код перебирает все данные в список
  • окончательный написанный файл не содержит все данные в списке

Может кто-нибудь сообщить мне о том, что происходит не так? Я попробую другой подход, чтобы написать содержимое в файл, но я все равно хотел бы знать, что здесь происходит и что я могу сделать, чтобы предотвратить его.

ответ

2

Класс StreamWriter имеет свой собственный буфер, если вы его не уничтожаете и не закрываете, остальная часть буфера будет потеряна, как вы заметили.

Существует несколько способов сброса этого буфера.

Вы можете явно смывать его:

sw.Flush(); 

, но это не совет, который я хотел бы дать, а вы должны избавиться от экземпляра StreamWriter, который также будет очищать буфер в основной поток, и как общий ориентир, любой объект, который реализует IDisposable, должен быть удален, когда вы закончите с ним.

Так изменить код так:

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); 
    } 
} 

Если вы хотите копать глубже, как StreamWriter класс работы я предлагаю изучения Reference Source Code of StreamWriter.

+0

Не назовет fs.Flush() перед закрытием также достичь желаемых результатов? – BugFinder

+2

Да, есть несколько способов добраться до финиша здесь, но я стою по моему руководству, всегда располагаю все объекты 'IDisposable'. –

+0

Достаточно честный. представляется разумным ориентиром. – BugFinder

Смежные вопросы