Delphi:替代使用Reset / ReadLn进行文本文件读取 [英] Delphi: Alternative to using Reset/ReadLn for text file reading

查看:771
本文介绍了Delphi:替代使用Reset / ReadLn进行文本文件读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想逐行处理文本文件。在过去的日子里,我将文件加载到一个 StringList 中:

i want to process a text file line by line. In the olden days i loaded the file into a 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中系统被锁定加载文件时,您无法真正指示进度。

Problem with that is once the file gets to be a few hundred megabytes, i have to allocate a huge chunk of memory; when really i only need enough memory to hold one line at a time. (Plus, you can't really indicate progress when you the system is locked up loading the file in step 1).

我尝试使用本机,并建议, Delphi提供的文件I / O例程:

The i tried using the native, and recommended, file I/O routines provided by Delphi:

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

分配的问题是没有选项来读取文件而不锁定(即 fmShareDenyNone )。前一个 stringlist 示例不支持no-lock,除非您将其更改为 LoadFromStream

Problem withAssign is that there is no option to read the file without locking (i.e. fmShareDenyNone). The former stringlist example doesn't support no-lock either, unless you change it to 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.

有没有替代分配 / ReadLn ,我可以逐行读取一个文件,而不需要共享锁?

Is there some alternative to Assign/ReadLn, where i can read a file line-by-line, without taking a sharing lock?

我宁可不直接访问Win32 CreateFile / ReadFile ,并且必须处理分配缓冲区并检测 CR LF CRLF

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.

我只想要重置 fmShareDenyNone

推荐答案

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

With recent Delphi versions, you can use TStreamReader. Construct it with your file stream, and then call its ReadLine method (inherited from TTextReader).

所有Delphi的选项版本是使用 Peter Below's StreamIO 单位,它给你 AssignStream 。它的工作方式就像 AssignFile ,但是对于流而不是文件名。一旦您使用该函数将流与 TextFile 变量相关联,您可以调用 ReadLn ,另一个/ O函数就像任何其他文件一样。

An option for all Delphi versions is to use Peter Below's StreamIO unit, which gives you AssignStream. It works just like AssignFile, but for streams instead of file names. Once you've used that function to associate a stream with a TextFile variable, you can call ReadLn and the other I/O functions on it just like any other file.

这篇关于Delphi:替代使用Reset / ReadLn进行文本文件读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆