2013-08-13 5 views
2

Я создаю текстовый файл на лету на основе данных, собранных в DataTable.Создание файла .txt из DataTable

В моем текущем (тестовом) наборе данных имеется 773 строки, которые я хочу разделить запятой (,) для каждого столбца и разбить каждую строку на отдельной строке. Вот моя попытка;

string FileName = "TEST_" + System.DateTime.Now.ToString("ddMMyyhhmm") + ".txt"; 

       StreamWriter sw = File.CreateText(@"PATH...." + FileName); 

       foreach (DataRow row in Product.Rows) 
       { 
        bool firstCol = true; 
        foreach (DataColumn col in Product.Columns) 
        { 
         if (!firstCol) sw.Write(","); 
         sw.Write(row[col].ToString()); 
         firstCol = false; 
        } 
        sw.WriteLine(); 
       } 

Выходной файл представляет собой текстовый файл, как и ожидалось. Мгновенно появляется большая часть данных, но текстовый файл никогда полностью не отображает 773 строки. Я пробовал это несколько раз, количество строк может варьироваться от 720 строк до 750 строк вплоть до частичного завершения строки 773, но оно никогда не заканчивается.

Я не вмешивался и не прекращал приложение в любое время.

Любые идеи?

+4

Вы пробовали обернуть «StreamWriter» в блок «using»? - Это приведет к сбросу буфера в базовый поток. - Повторите попытку 'sw.Flush()' после цикла foreach. – ebb

+0

@ebb Использование sw.Flush() сделал трюк, не могли бы вы ответить на него и, возможно, объяснить, почему, я с радостью соглашусь. Благодарю. – William

+1

@ Clev231 по этой причине, прочитайте: http://stackoverflow.com/questions/2417978/what-is-the-difference-between-streamwriter-flush-and-streamwriter-close –

ответ

2

Короткий ответ

Вы должны очистить Stream, либо обернув StreamWriter в using блоке, или позвоните sw.Flush() в конце вашего цикла foreach.


Длинный ответ

При использовании StreamWriter любого вида (StreamWriter, BinaryWriter, TextWriter), запись в основной поток/устройства (в вашем случае файл) - он не будет писать прямо к файлу, так как это дорого, по сравнению с использованием буфера.

(1) Представьте себе следующее:

  • Вы Перебор 10,000 записей
  • Каждая запись записывается в файл непосредственно при вызове .Write(), прежде чем перейти к следующей записи.

(2) Как это действительно работает:

  • Вы Перебор 10,000 записей
  • Каждая запись записывается в буфер при вызове .Write(), прежде чем перейти к следующей записи.
  • Когда буфер достигнет определенного размера/количества элементов, он будет сбрасываться на диск.

Вы можете видеть, что с помощью (2) вы получите много производительности ввода-вывода по сравнению с (1), так как каждая новая запись не должна быть немедленно записана в файл.

Так что (1) нужно будет записать в файл 10 000 раз, тогда как (2) нужно написать только часть того, что нужно (1) (которое может быть 5000 раз, 2000 раз - это зависит от того, как буфер реализован).

обертывания Stream в using блоке, или позвонив по телефону Flush() на него всякий раз, когда вы закончите с Stream сделает его очистить буфер (и недостающие данные) в файл.

1

Я не могу точно сказать, в чем причина, но я вижу, что вам (и нам) нужна дополнительная информация.

Давайте начнем с того, что знаем, сколько строк находится в Product.Rows, поставив точку останова и посмотри в окне count.

после этого, и если количество строк совпадает с тем, что было, вы поставили счетчик в цикле и проверили, что он проходит через цикл столько же раз. наконец, попробуйте найти последнюю строку, записанную в файл, и отлаживать эту строку в цикле шаг за шагом. вы можете получить исключение (маловероятно, но возможность), и вы можете узнать больше о проблеме

+0

Спасибо за ваш ответ, однако я должен заявили, что я уже знал, что таблица содержала 773 строки, текстовый файл иногда даже показывался до 773-й строки. sw.Flush() решила мою проблему. – William

+1

@ Clev231 вы хотите сказать, что вы просто не закрывали файл ... вы должны всегда использовать инструкцию «using» при работе с файлами и потоками –

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