Щоб знайти найшвидший спосіб прочитати файл за рядком, вам доведеться зробити порівняльний аналіз. Я зробив кілька невеликих тестів на своєму комп’ютері, але ви не можете очікувати, що мої результати стосуються вашого середовища.
Використання StreamReader.ReadLine
Це в основному ваш метод. Чомусь ви встановлюєте розмір буфера на найменше можливе значення (128). Підвищення цього в цілому збільшить ефективність роботи. За замовчуванням розмір 1,024, а інші хороші варіанти - 512 (розмір сектору в Windows) або 4 066 (розмір кластера в 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
допомогою фіксованого розміру буфера 1,024. На моєму комп’ютері це призводить до дещо кращої продуктивності порівняно з вашим кодом з розміром буфера 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
), ви можете використовувати власний код, але слід збільшити розмір буфера.
Fastest
ви маєте на увазі з точки зору продуктивності чи розвитку?