Ok, I used your baseline code to rewrite my VB.NET function. It is very fast
and efficient. The only thing I needed to added was a check to see if the
last character was a LF and increment the total if not; I get the correct
number of lines every time! Processing ~200MB of log files (209 files)
occurs extremely fast (only added 2 seconds overall to the date/time indexing
functions I was already performing.)
Thanks a million!!!
Here's my new VB.NET function to benefit anyone else needing to count lines
in a file in VB.NET:
Public Function GetLineCount(ByVal FileName As String) As Integer
Dim total As Integer = 0
If File.Exists(FileName) Then
Dim buffer(32 * 1024) As Char
Dim i As Integer
Dim read As Integer
Dim reader As TextReader = File.OpenText(FileName)
read = reader.Read(buffer, 0, buffer.Length)
While (read > 0)
i = 0
While i < read
If buffer(i) = Chr(10) Then
total += 1
End If
i += 1
End While
read = reader.Read(buffer, 0, buffer.Length)
End While
reader.Close()
reader = Nothing
If Not buffer(i - 1) = Chr(10) Then
total += 1
End If
End If
Return total
End Function
Jon Skeet said:
mesterak said:
So how can I count the lines of the file without loading the whole file into
memory as a string and counting lines?
By reading chunks at a time (using StreamReader) and counting '\n'
occurrences.
Here's some sample code:
using System;
using System.IO;
class Test
{
static int CountLines (TextReader reader)
{
char[] buffer = new char[32*1024]; // Read 32K chars at a time
int total=1; // All files have at least one line!
int read;
while ( (read=reader.Read(buffer, 0, buffer.Length)) > 0)
{
for (int i=0; i < read; i++)
{
if (buffer
=='\n')
{
total++;
}
}
}
return total;
}
static void Main(string[] args)
{
foreach (string file in args)
{
using (StreamReader reader = new StreamReader(file))
{
Console.WriteLine ("{0}: {1} lines", file,
CountLines(reader));
}
}
}
}