| 
			Author: Jonas Bilinkevicius
How to count the lines of text contained in a text file
Answer:
Solve 1:
The fastest way would be to count the instances of #13#10 yourself. However you 
need to be careful because #13 and #10 could easily be swapped to give #10#13 
instead which makes this kind of counting more difficult. In this case it's far 
easier just to count the instances of one of them and this has the bonus of being 
more compatible with non-Windows (ie. non CR/LF'd) files - not all operating 
systems bother with both #13 and #10. The following is a basic implementation of 
the code:
1   
2   function CountLines(const FileName: string): integer;
3   const
4     BufferSize = 1024;
5     SearchByte = 10;
6   var
7     FileHandle, BytesRead, Index: integer;
8     Buffer: array[1..BufferSize] of byte;
9   begin
10    FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite);
11    BytesRead := FileRead(FileHandle, Buffer[1], BufferSize);
12    if (BytesRead > 0) then
13      Result := 1
14    else
15      Result := 0;
16    repeat
17      for Index := 1 to Min(BufferSize, BytesRead) do
18      begin
19        if (Buffer[Index] = SearchByte) then
20          Inc(Result);
21      end;
22      BytesRead := FileRead(FileHandle, Buffer[1], BufferSize);
23    until
24      BytesRead <= 0;
25    FileClose(FileHandle);
26  end;
This code is searching for #10's in the file, and treating this as a line 
delimeter. It takes care of the case where an empty file has 0 lines but a file 
with no #10s has one line in the initialisation of the Result return value. You can 
easily modify the seach byte and/or the buffer size.
Solve 2:
If it is a smaller file (< 1 MB) load it into a TStringlist and look at the 
stringlists Count property. If it is larger you need to read it completely and 
count lines. A simple loop would be this:
27  
28  function CountLines(const filename: string): Integer;
29  var
30    buffer: array[0..4095] of Char;
31    f: Textfile;
32  begin
33    Result := 0;
34    Assignfile(f, filename);
35    Reset(f);
36    try
37      SetTextBuffer(f, buffer, sizeof(buffer));
38      while not Eof(f) do
39      begin
40        readLn(f);
41        Inc(result);
42      end;
43    finally
44      Closefile(f);
45    end;
46  end;
Using a larger than the default buffer of 128 bytes speeds the reading somewhat.
Solve 3:
Buffering can help quit a bit:
47  
48  function TextLineCount_BufferedStream(const Filename: TFileName): Integer;
49  const
50    MAX_BUFFER = 1024 * 1024;
51  var
52    oStream: TFileStream;
53    sBuffer: string;
54    iBufferSize: Integer;
55    iSeek: Integer;
56    bCarry: Boolean;
57  begin
58    Result := 0;
59    bCarry := False;
60    oStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
61    try
62      SetLength(sBuffer, MAX_BUFFER);
63      repeat
64        iBufferSize := oStream.read(sBuffer[1], MAX_BUFFER);
65        if iBufferSize <= 0 then
66          break;
67        {Skip LFs that follow a CR - even if it falls in seperate buffers}
68        iSeek := 1;
69        if bCarry and (sBuffer[1] = #10) then
70          Inc(iSeek);
71        while iSeek <= iBufferSize do
72        begin
73          case sBuffer[iSeek] of
74            #10:
75              Inc(Result);
76            #13:
77              if iSeek = iBufferSize then
78                Inc(Result)
79              else if sBuffer[iSeek + 1] <> #10 then
80                Inc(Result)
81              else
82              begin
83                Inc(Result);
84                Inc(iSeek);
85              end;
86          end;
87          Inc(iSeek);
88        end;
89        {Set carry flag for next pass}
90        bCarry := (sBuffer[iBufferSize] = #13);
91      until
92        iBufferSize < MAX_BUFFER;
93    finally
94      FreeAndNil(oStream);
95    end;
96  end;
			 |