我想逐行处理文本文件。在过去,我将文件加载到StringList:
slFile := TStringList.Create();
slFile.LoadFromFile(filename);
for i := 0 to slFile.Count-1 do
begin
oneLine := slFile.Strings[i];
//process the line
end;
问题是一旦文件达到几百兆字节,我必须分配一大块内存;当我真的只需要足够的内存来一次保存一行时。(另外,当系统在步骤 1 中锁定加载文件时,您无法真正指示进度)。
我尝试使用 Delphi 提供的本机和推荐的文件 I/O 例程:
var
f: TextFile;
begin
Reset(f, filename);
while ReadLn(f, oneLine) do
begin
//process the line
end;
问题Assign是没有选项可以在没有锁定的情况下读取文件(即fmShareDenyNone)。前stringlist一个示例也不支持无锁,除非您将其更改为LoadFromStream:
slFile := TStringList.Create;
stream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone);
slFile.LoadFromStream(stream);
stream.Free;
for i := 0 to slFile.Count-1 do
begin
oneLine := slFile.Strings[i];
//process the line
end;
So now even though i've gained no locks being held, i'm back to loading the entire file into memory.
Is there some alternative to Assign/ReadLn, where i can read a file line-by-line, without taking a sharing lock?
i'd rather not get directly into Win32 CreateFile/ReadFile, and having to deal with allocating buffers and detecting CR, LF, CRLF's.
i thought about memory mapped files, but there's the difficulty if the entire file doesn't fit (map) into virtual memory, and having to maps views (pieces) of the file at a time. Starts to get ugly.
i just want Reset with fmShareDenyNone!