Чтобы найти самый быстрый способ чтения файла построчно, вам нужно сделать несколько сравнительных тестов.Я провел несколько небольших тестов на своем компьютере, но вы не можете ожидать, что мои результаты применимы к вашей среде.
Использование StreamReader.ReadLine
Это в основном ваш метод.По какой-то причине вы устанавливаете размер буфера наименьшее возможное значение (128).Увеличение этого в целом увеличит производительность.Размер по умолчанию - 1024, а другие хорошие варианты - 512 (размер сектора в Windows) или 4096 (размер кластера в NTFS).Вам нужно будет запустить тест для определения оптимального размера буфера.Больший буфер - если не быстрее - по крайней мере, не медленнее, чем меньший буфер.
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
String line;
while ((line = streamReader.ReadLine()) != null)
// Process line
}
Конструктор FileStream
позволяет указать FileOptions .Например, если вы читаете большой файл последовательно от начала до конца, вы можете воспользоваться FileOptions.SequentialScan
.Опять же, бенчмаркинг - лучшее, что вы можете сделать.
Использование File.ReadLines
Это очень похоже на ваше собственное решение, за исключением того, что оно реализовано с использованием StreamReader
с фиксированным размером буфера 1024.На моем компьютере это приводит к несколько лучшей производительности по сравнению с вашим кодом с размером буфера 128. Однако вы можете получить такое же увеличение производительности, используя больший размер буфера.Этот метод реализован с использованием блока итератора и не использует память для всех строк.
var lines = File.ReadLines(fileName);
foreach (var line in lines)
// Process line
Использование File.ReadAllLines
Это очень похоже на предыдущий методза исключением того, что этот метод увеличивает список строк, используемых для создания возвращаемого массива строк, поэтому требования к памяти выше.Однако он возвращает String[]
, а не IEnumerable<String>
, позволяя вам произвольно обращаться к строкам.
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}
Использование String.Split
Этот метод значительномедленнее, по крайней мере, для больших файлов (проверено на файле размером 511 КБ), вероятно, из-за того, как реализован String.Split
.Он также выделяет массив для всех строк, увеличивая требуемую память по сравнению с вашим решением.
using (var streamReader = File.OpenText(fileName)) {
var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
// Process line
}
Я предлагаю использовать File.ReadLines
, потому что он чистый и эффективный.Если вам требуются специальные параметры обмена (например, вы используете FileShare.ReadWrite
), вы можете использовать свой собственный код, но вы должны увеличить размер буфера.