Delphi:使用Reset/ReadLn替代文本文件读取

Ian*_*oyd 12 delphi readline text-files

我想逐行处理文本文件.在以前我把文件加载到StringList:

slFile := TStringList.Create();
slFile.LoadFromFile(filename);

for i := 0 to slFile.Count-1 do
begin
   oneLine := slFile.Strings[i];
   //process the line
end;
Run Code Online (Sandbox Code Playgroud)

这一问题是一旦文件到达是一个几百兆,我不得不分配一个巨大的内存块; 当我真的只需要足够的内存来保持一行一行时.(另外,当系统在步骤1中锁定加载文件时,您无法真正指示进度).

我尝试使用Delphi提供的本机和推荐的文件I/O例程:

var
   f: TextFile;
begin
   Reset(f, filename);
   while ReadLn(f, oneLine) do
   begin
       //process the line
   end;
Run Code Online (Sandbox Code Playgroud)

问题Assign是没有锁定(即fmShareDenyNone)没有选项来读取文件.前一个stringlist示例也不支持no-lock,除非您将其更改为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;
Run Code Online (Sandbox Code Playgroud)

所以现在即使我没有获得锁定,我又回到将整个文件加载到内存中.

有什么替代Assign/ ReadLn,我可以逐行读取文件,而不需要共享锁?

我宁愿不直接进入的Win32 CreateFile/ ReadFile,并具有处理分配缓冲区和检测CR,LF,CRLF的.

我考虑过内存映射文件,但如果整个文件不适合(映射)到虚拟内存中,并且必须一次映射文件的视图(片段),则会遇到困难.开始变得难看.

我只是想ResetfmShareDenyNone!

Rob*_*edy 15

使用最新的Delphi版本,您可以使用TStreamReader.用文件流构造它,然后调用它的ReadLine方法(继承自TTextReader).

所有Delphi版本的选项是使用Peter Below的StreamIO单元,它可以为您提供AssignStream.它就像AssignFile,但对于流而不是文件名.一旦您使用该函数将流与TextFile变量相关联,您就可以像调用ReadLn任何其他文件一样调用它上面的其他I/O函数.

  • 请使用单词,Ian,而不仅仅是链接.我不知道你想要通信的是什么. (4认同)
  • 如果TStreamReader不是那么血腥*会很棒.从CodeCentral获取Uffe Kousgaard的[文本阅读"基准"](http://cc.embarcadero.com/Item/27692)并添加TStreamReader实现.运行它并观察CPU刻录.它甚至不受I/O限制. (3认同)