Является ли StreamReader.Readline () действительно самым быстрым способом подсчета строк в файле?
Оглядываясь некоторое время, я обнаружил довольно много дискуссий о том, как определить количество строк в файле.
Например, эти три:
C # Как мне считать строки в текстовом файле
Определить количество строк в текстовом файле
Как быстро считать строки?
Итак, я пошел дальше и в итоге использовал наиболее эффективный (хотя бы по памяти?) Метод, который я смог найти:
private static int countFileLines(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null)
{
i++;
}
return i;
}
}
Но это занимает вечность, когда сами строки из файла очень длинные. Неужели нет более быстрого решения этой проблемы?
Я пытался использоватьStreamReader.Read()
или жеStreamReader.Peek()
но я не могу (или не знаю, как) заставить один из них перейти к следующей строке, как только появится «материал» (символы? текст?).
Есть идеи, пожалуйста?
ВЫВОДЫ / РЕЗУЛЬТАТЫ (После запуска некоторых тестов на основе предоставленных ответов):
Я проверил 5 методов ниже на двух разных файлах, и я получил согласованные результаты, которые, кажется, указывают, что старыйStreamReader.ReadLine()
по-прежнему один из самых быстрых способов ... Если честно, я озадачен после всех комментариев и обсуждения в ответах.
Файл № 1:
Размер: 3631 КБ
Строки: 56 870
Результаты в секундах для файла № 1:
0.02 -> метод ReadLine.
0.04 -> Метод чтения.
0.29 -> Метод ReadByte.
0.25 -> Метод Readlines.Count.
0.04 -> метод ReadWithBufferSize.
Файл № 2:
Размер: 14,499 КБ
Линии: 213,424
Результаты в секундах для файла № 1:
0.08 -> метод ReadLine.
0.19 -> Метод чтения.
1.15 -> Метод ReadByte.
1.02 -> метод Readlines.Count.
0.08 -> метод ReadWithBufferSize.
Вот 5 методов, которые я протестировал на основе всех полученных отзывов:
private static int countWithReadLine(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null)
{
i++;
}
return i;
}
}
private static int countWithRead(string filePath)
{
using (StreamReader _reader = new StreamReader(filePath))
{
int c = 0, count = 0;
while ((c = _reader.Read()) != -1)
{
if (c == 10)
{
count++;
}
}
return count;
}
}
private static int countWithReadByte(string filePath)
{
using (Stream s = new FileStream(filePath, FileMode.Open))
{
int i = 0;
int b;
b = s.ReadByte();
while (b >= 0)
{
if (b == 10)
{
i++;
}
b = s.ReadByte();
}
return i;
}
}
private static int countWithReadLinesCount(string filePath)
{
return File.ReadLines(filePath).Count();
}
private static int countWithReadAndBufferSize(string filePath)
{
int bufferSize = 512;
using (Stream s = new FileStream(filePath, FileMode.Open))
{
int i = 0;
byte[] b = new byte[bufferSize];
int n = 0;
n = s.Read(b, 0, bufferSize);
while (n > 0)
{
i += countByteLines(b, n);
n = s.Read(b, 0, bufferSize);
}
return i;
}
}
private static int countByteLines(byte[] b, int n)
{
int i = 0;
for (int j = 0; j < n; j++)
{
if (b[j] == 10)
{
i++;
}
}
return i;
}