我想逐行处理文本文件。在过去,我将文件加载到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
!