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

标签 delphi text-files readline

我想逐行处理文本文件。过去,我将文件加载到 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 提供的 native 且推荐的文件 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,并且必须处理分配缓冲区和检测CRLFCRLF 的。

我考虑过内存映射文件,但是如果整个文件不适合(映射)到虚拟内存中,并且必须一次映射文件的 View (片段),就会出现困难。开始变得丑陋。

我只想使用fmShareDenyNone重置!

最佳答案

对于最新的 Delphi 版本,您可以使用 TStreamReader 。使用您的文件流构建它,然后调用 its ReadLine method (继承自TTextReader)。

所有 Delphi 版本的一个选项是使用 Peter Below's StreamIO unit ,这将为您提供AssignStream。它的工作方式与AssignFile 类似,但针对的是流而不是文件名。一旦您使用该函数将流与 TextFile 变量关联起来,您就可以像调用任何其他文件一样调用 ReadLn 以及其他 I/O 函数。

关于Delphi:使用 Reset/ReadLn 读取文本文件的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2815839/

相关文章:

delphi - 如何将 DLL 中的表单嵌入到 Inno Setup 向导页面中?

python - 在 Python 中读入文件并跳过文本文件的 header 部分

javascript - 使用 readline 在 javascript 中进行一系列用户输入,其中相应的问题存储在数组中

php - php中readline与fread/fgets的区别

r - 将 R read.csv 转换为 readLines 批处理?

delphi - FireMonkey3下检测本地IP地址

delphi - 什么解释了这种奇怪的 PeekMessage 行为(尝试处理完整的消​​息队列,过滤特定消息)?

delphi - 对于 TBitmap,FMX 中是否有相当于 FloodFill 的功能?

python - 搜索文本文件 - 高分(使用 Python)

Python:BeautifulSoup UnboundLocalError