我想逐行处理一个文本文件。从前,我会将文件加载到一个StringList
中:
slFile := TStringList.Create();
slFile.LoadFromFile(filename);
for i := 0 to slFile.Count-1 do
begin
oneLine := slFile.Strings[i];
//process the line
end;
问题在于,一旦文件变得几百兆字节,我就不得不分配一个巨大的内存块;而实际上我只需要足够的内存来一次性保存一行。 (另外,在第一步中加载文件时系统锁定,你不能真正指示进度)。
然后我尝试使用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;
尽管我没有获得任何锁定,但现在我又回到了将整个文件加载到内存中的情况。
是否有一些替代Assign
/ReadLn
的方法,可以逐行读取文件,而不需要获取共享锁定?
我不想直接使用Win32 CreateFile
/ReadFile
,因为这样要处理分配缓冲区以及检测CR
、LF
、CRLF
等问题。
我想过使用内存映射文件,但是如果整个文件无法(映射)到虚拟内存中,则会出现困难,并且必须一次映射文件的视图(片段)。这开始变得麻烦。
我只想要带有fmShareDenyNone
选项的Reset
!