Я хочу читать текстовый файл построчно. Я хотел знать, насколько эффективно я делаю это в рамках .NET C #.
Это то, что я пытаюсь до сих пор:
var filestream = new System.IO.FileStream(textFilePath,
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite);
var file = new System.IO.StreamReader(filestream, System.Text.Encoding.UTF8, true, 128);
while ((lineOfText = file.ReadLine()) != null)
{
//Do something with the lineOfText
}
c#
.net
performance
file-io
text-files
Лорен С Фортнер
источник
источник
Fastest
вы имеете в виду от исполнения или перспективы развития?filestream = new FileStream
вusing()
заявлении, чтобы избежать возможных раздражающих проблем с заблокированным дескриптором файлаОтветы:
Чтобы найти самый быстрый способ чтения файла построчно, вам нужно сделать несколько тестов. Я провел несколько небольших тестов на своем компьютере, но вы не можете ожидать, что мои результаты применимы к вашей среде.
Использование StreamReader.ReadLine
Это в основном ваш метод. По какой-то причине вы устанавливаете размер буфера наименьшее возможное значение (128). Увеличение этого в целом увеличит производительность. Размер по умолчанию - 1024, а другие хорошие варианты - 512 (размер сектора в Windows) или 4096 (размер кластера в NTFS). Вам нужно будет запустить тест для определения оптимального размера буфера. Больший буфер - если не быстрее - по крайней мере, не медленнее, чем меньший буфер.
FileStream
Конструктор позволяет указать FileOptions . Например, если вы читаете большой файл последовательно от начала до конца, вы можете извлечь из этого пользуFileOptions.SequentialScan
. Опять же, бенчмаркинг - лучшее, что вы можете сделать.Использование File.ReadLines
Это очень похоже на ваше собственное решение, за исключением того, что оно реализовано
StreamReader
с использованием фиксированного размера буфера 1024. На моем компьютере это приводит к несколько лучшей производительности по сравнению с вашим кодом с размером буфера 128. Однако вы можете получить такое же увеличение производительности, используя больший размер буфера. Этот метод реализован с использованием блока итератора и не использует память для всех строк.Использование File.ReadAllLines
Это очень похоже на предыдущий метод, за исключением того, что этот метод увеличивает список строк, используемых для создания возвращаемого массива строк, поэтому требования к памяти выше. Тем не менее, он возвращает
String[]
и неIEnumerable<String>
дает вам возможность случайного доступа к линиям.Использование String.Split
Этот метод значительно медленнее, по крайней мере, для больших файлов (проверено на файле размером 511 КБ), вероятно, из-за того, как
String.Split
он реализован Он также выделяет массив для всех строк, увеличивая требуемую память по сравнению с вашим решением.Мое предложение состоит в том, чтобы использовать,
File.ReadLines
потому что это чисто и эффективно. Если вам требуются специальные параметры обмена (например, вы используетеFileShare.ReadWrite
), вы можете использовать свой собственный код, но вы должны увеличить размер буфера.источник
Если вы используете .NET 4, просто используйте,
File.ReadLines
который делает все это за вас. Я подозреваю, что он очень похож на ваш, за исключением того, что он также может использоватьFileOptions.SequentialScan
и больший буфер (128 кажется очень маленьким).источник
ReadLines()
является то, что он ленивый, поэтому хорошо работает с LINQ.Хотя
File.ReadAllLines()
это один из самых простых способов чтения файла, он также является одним из самых медленных.Если вы просто хотите читать строки в файле без особых усилий, в соответствии с этими тестами , самый быстрый способ чтения файла - это старый метод:
Однако, если вам приходится много делать с каждой строкой, то в этой статье делается вывод, что лучшим способом является следующий (и быстрее предварительно выделить строку [], если вы знаете, сколько строк вы собираетесь читать):
источник
Используйте следующий код:
Это была ОГРОМНАЯ разница в производительности чтения.
Это происходит за счет потребления памяти, но оно того стоит!
источник
File.ReadAllLines
Есть хорошая тема на этот счет в вопросе переполнения стека. Является ли «возврат доходности» более медленным, чем возврат «старой школы»? ,
Это говорит:
источник
Если размер файла не велик, то быстрее прочитать весь файл и затем разделить его
источник
File.ReadAllLines()
File.ReadAllLines
есть фиксированный размер буфера, так как размер файла известен.File.ReadAllLines
создает список и добавляет его в этот цикл с использованиемStreamReader.ReadLine
(с возможным перераспределением базового массива). Этот метод использует размер буфера по умолчанию, равный 1024. ОнStreamReader.ReadToEnd
позволяет избежать синтаксического анализа строки, и размер буфера может быть установлен в конструкторе при желании.Если у вас достаточно памяти, я нашел некоторый прирост производительности, прочитав весь файл в поток памяти , а затем открыв для этого читатель потока, чтобы прочитать строки. Если вы все равно планируете прочитать весь файл, это может привести к некоторым улучшениям.
источник
File.ReadAllLines
кажется, лучший выбор тогда.Вы не можете получить немного быстрее, если вы хотите использовать существующий API для чтения строк. Но чтение больших кусков и поиск каждой новой строки в буфере чтения вручную, вероятно, будет быстрее.
источник