Czy StreamReader.Readline () naprawdę jest najszybszą metodą liczenia linii w pliku?
Rozglądając się przez chwilę, znalazłem sporo dyskusji na temat obliczania liczby wierszy w pliku.
Na przykład te trzy:
c # jak liczyć linie w pliku tekstowym
Określ liczbę linii w pliku tekstowym
Jak szybko liczyć linie?
Więc poszedłem naprzód i skończyłem używając metody, która wydaje się być najbardziej wydajną (przynajmniej pod względem pamięci?) Metodą, którą mogłem znaleźć:
private static int countFileLines(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null)
{
i++;
}
return i;
}
}
Ale to trwa wiecznie, gdy same linie z pliku są bardzo długie. Czy naprawdę nie ma szybszego rozwiązania tego problemu?
Próbowałem użyćStreamReader.Read()
lubStreamReader.Peek()
ale nie mogę (lub nie wiem jak) sprawić, że oba z nich przejdą do następnej linii, gdy tylko pojawi się „rzeczy” (znaki? tekst?).
Masz jakieś pomysły?
WNIOSKI / WYNIKI (Po przeprowadzeniu kilku testów na podstawie udzielonych odpowiedzi):
Przetestowałem 5 poniższych metod na dwóch różnych plikach i otrzymałem spójne wyniki, które wydają się wskazywać na to, że jest staryStreamReader.ReadLine()
jest wciąż jednym z najszybszych sposobów ... Szczerze mówiąc, jestem zakłopotany po wszystkich komentarzach i dyskusjach w odpowiedziach.
Plik nr 1:
Rozmiar: 3631 KB
Linie: 56,870
Wyniki w sekundach dla pliku nr 1:
0.02 -> Metoda ReadLine.
0.04 -> Metoda odczytu.
0,29 -> Metoda ReadByte.
0.25 -> Metoda Readlines.Count.
0.04 -> Metoda ReadWithBufferSize.
Plik nr 2:
Rozmiar: 14 499 KB
Linie: 213,424
Wyniki w sekundach dla pliku nr 1:
0.08 -> Metoda ReadLine.
0.19 -> Metoda odczytu.
1.15 -> Metoda ReadByte.
1.02 -> Metoda Readlines.Count.
0.08 -> Metoda ReadWithBufferSize.
Oto 5 metod, które testowałem na podstawie wszystkich otrzymanych opinii:
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;
}