Когда я должен сохранить файл, и когда я должен прочитать его построчно? - PullRequest
3 голосов
/ 21 июля 2010

Представьте, что у меня есть приложение C #, которое редактирует текстовые файлы. Техника, используемая для каждого файла, может быть:

1) Считайте файл сразу в строку, внесите изменения и запишите строку поверх существующего файла:

string fileContents = File.ReadAllText(fileName);

// make changes to fileContents here...

using (StreamWriter writer = new StreamWriter(fileName))
{
    writer.Write(fileContents);
}

2) Читайте файл построчно, записывая изменения во временный файл, затем удаляя источник и переименовывая временный файл:

using (StreamReader reader = new StreamReader(fileName))
{
    string line;

    using (StreamWriter writer = new StreamWriter(fileName + ".tmp"))
    {
        while (!reader.EndOfStream)
        {
            line = reader.ReadLine();
            // make changes to line here
            writer.WriteLine(line);
        }
    }
}
File.Delete(fileName);
File.Move(fileName + ".tmp", fileName);

Каковы соображения производительности с этими параметрами?

Мне кажется, что при чтении по одной строке или чтении всего файла одновременно будет прочитано одинаковое количество данных, а время на диске будет доминировать во времени выделения памяти. Тем не менее, как только файл находится в памяти, ОС может свободно выгружать его, и когда это происходит, польза от такого большого чтения теряется. С другой стороны, при работе с временным файлом, когда дескрипторы закрыты, мне нужно удалить старый файл и переименовать временный файл, что влечет за собой затраты.

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

Я предполагаю, что в некоторых случаях лучше обрабатывать файл, а в других лучше работать построчно. У меня вопрос, каковы условия для этих двух случаев?

1 Ответ

4 голосов
/ 21 июля 2010

в некоторых случаях лучше копировать файл, а в других - лучше работать по строкам.

Очень близко; за исключением того, что построчное чтение на самом деле является гораздо более конкретным случаем. Фактические варианты, которые мы хотим различить, - это ReadAll и использование буфера. ReadLine делает предположения - самое большое из них состоит в том, что в файле действительно есть строки, и они имеют разумную длину! Если мы не можем сделать это предположение о файле, мы хотим выбрать определенный размер буфера и прочитать его независимо от того, достиг ли мы конца строки или нет.

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

Самый простой - прочитайте все сразу.

Производительность становится проблемой? Работает ли это приложение с неконтролируемыми файлами, поэтому их размер не предсказуем? Просто несколько примеров, где вы хотите разбить его на части.

...