Delphi:替代使用Reset / ReadLn进行文本文件读取 [英] Delphi: Alternative to using Reset/ReadLn for text file reading
问题描述
我想逐行处理文本文件。在过去的日子里,我将文件加载到一个 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屋!