gpt4 book ai didi

delphi - TStringList.LoadFromFile - 大文本文件的异常

转载 作者:行者123 更新时间:2023-12-03 15:03:44 32 4
gpt4 key购买 nike

我正在运行 Delphi RAD Studio XE2。

我有一些非常大的文件,每个文件都包含大量行。这些行本身很小——只有 3 个制表符分隔的 double 。我想使用 TStringList.LoadFromFile 将文件加载到 TStringList 中,但这会引发大文件的异常。

对于 200 万行(大约 1GB)的文件,我收到 EIntOverflow 异常。对于较大的文件(例如 2000 万行,大约 10GB),我会收到 ERangeCheck 异常。

我有 32GB 的 RAM 可以使用,我只是想加载这个文件并快速使用它。这是怎么回事?我还有什么其他选择?我可以使用具有大缓冲区的文件流将此文件加载到 TStringList 中吗?如果可以的话请举个例子。

最佳答案

当 Delphi 在 Delphi 2009 中切换到 Unicode 时,TStrings.LoadFromStream()方法( TStrings.LoadFromFile() 内部调用)对于大型流/文件变得非常低效。

内部,LoadFromStream()整个文件作为 TBytes 读入内存,然后将其转换为 UnicodeString使用TEncoding.GetString() (它将字节解码为 TCharArray ,将其复制到最终的 UnicodeString ,然后释放数组),然后解析 UnicodeString (当 TBytes 仍在内存中时)根据需要将子字符串添加到列表中。

所以,就在 LoadFromStream() 之前退出时,内存中存在文件数据的四个副本 - 三个副本占用的空间更糟 filesize * 3内存字节(其中每个副本都使用自己的连续内存块+一些 MemoryMgr 开销),以及解析子字符串的一个副本!当然,前三个副本在 LoadFromStream() 时被释放。实际上退出了。但这解释了为什么您在到达该点之前会出现内存错误 - LoadFromStream()正在尝试使用 3-4 GB 内存来加载 1GB 文件,而 RTL 的内存管理器无法处理该问题。

如果要将大文件的内容加载到 TStringList ,你最好使用 TStreamReader而不是LoadFromFile()TStreamReader使用缓冲文件 I/O 方法以小块的形式读取文件。只需调用其 ReadLine()循环中的方法,Add()将每一行添加到 TStringList 。例如:

//MyStringList.LoadFromFile(filename);
Reader := TStreamReader.Create(filename, true);
try
MyStringList.BeginUpdate;
try
MyStringList.Clear;
while not Reader.EndOfStream do
MyStringList.Add(Reader.ReadLine);
finally
MyStringList.EndUpdate;
end;
finally
Reader.Free;
end;

也许有一天,LoadFromStream()可能会被重写以使用 TStreamReader内部是这样的。

关于delphi - TStringList.LoadFromFile - 大文本文件的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27007904/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com