这么个简单问题,居然在网上找不到现成的代码。只好自己做了。
1、TStringList 法:
function GetTextLineCount_SL(const strFileName: string): UInt64;
begin
with TStringList.Create do
begin
LoadFromFile(strFileName);
Result := Count;
Free;
end;
end;
这种方案,只能针对小文件,大文件就不行了。
既然是文本文件,那么可以使用 readln 方法来读取试试。
2、TextFile 法:
function GetTextLineCount_TF(const strFileName: string): UInt64;
var
F: TextFile;
begin
Result := 0;
AssignFile(F, strFileName);
SetTextBuf(F, Buffer);
Reset(F);
while not eof(F) do
begin
Readln(F);
Inc(Result);
end;
CloseFile(F);
end;
这种方案。有个缺陷:它返回的行数和 TStringlist 法返回的行数是不一样的。
原因:TStringlist 法,#13#10 当成换行,#13、#10也会被当成换行进行计数(具体可以参看 Delphi 源码)。而 readln 则不会。
看来针对大文件,还得另想它法。
试试文件流的方式。
3、FileStream 法(Linux 下,只用 #10 作为换行符,而 Windows 下,#13#10、#13、#10,都可作为换行符):
function GetTextLineCount_FS(const strFileName: string; const bLinux: Boolean = False): UInt64;
var
FS : TFileStream;
I, Count: Integer;
startPos: Integer;
partXPos: Integer;
begin
Result := 0;
startPos := 0;
partXPos := 0;
FS := TFileStream.Create(strFileName, fmOpenRead);
try
Count := FS.Size;
if bLinux then
begin
while FS.Position < Count do
begin
FS.Read(Buffer[0], c_intLength);
startPos := startPos + c_intLength;
if startPos > Count then
partXPos := startPos - Count;
for I := 0 to c_intLength - 1 - partXPos do
begin
if (Buffer[I] = #10) then
Inc(Result);
end;
end;
end
else
begin
while FS.Position < Count do
begin
FS.Read(Buffer[0], c_intLength);
startPos := startPos + c_intLength;
if startPos > Count then
partXPos := startPos - Count;
for I := 0 to c_intLength - 1 - partXPos do
begin
if (Buffer[I] = #13) and (Buffer[I + 1] = #10) then
Inc(Result)
else if (Buffer[I] = #13) and (Buffer[I + 1] <> #10) then
Inc(Result)
else if (Buffer[I] <> #13) and (Buffer[I + 1] = #10) then
Inc(Result);
end;
end;
end;
finally
FS.Free;
end;
end;
测试:(函数名、行数、耗时)
30M 文本文件:
GetTextLineCount_SL 828125 987毫秒
GetTextLineCount_TF 828092 484毫秒
GetTextLineCount_FS 828125 96毫秒
600M 文本文件:
GetTextLineCount_SL < 不支持 >
GetTextLineCount_TF 14177571 8758毫秒
GetTextLineCount_FS 14181548 1659毫秒(Linux 829毫秒)
第三种方案最好,即兼容第一种,又比第一种效率高出 10 倍左右。