- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在运行 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/
我使用Delphi LoadFromFile函数插入Table1BLOBFIELD.LoadFromFile('C:\xxx.avi') 和 SaveToFile 命令来检索。这种插入/检索相当耗时(
如何保持.txt文件中存在的空格?在.txt文件中,它表示: text :text text1 :text1 text23 :text2 text345 :text3 如果我写这段
我得到了一个 .png 文件,该文件在 Windows 资源管理器中正确呈现,但不会加载到我的应用程序中。每当我尝试加载文件时,它都会抛出 EPNGInvalidFileHeader异常(except
我正在尝试打开一个 StringList 的 txt 文件,但如果我打开 UTF-8 格式,它无法加载,这很令人困惑,因为我有 Unicode XE2,我在这里错过了一些愚蠢的东西吗? 简单示例 Sl
我正在运行 Delphi RAD Studio XE2。 我有一些非常大的文件,每个文件都包含大量行。这些行本身很小——只有 3 个制表符分隔的 double 。我想使用 TStringList.Lo
我想也许我开始在这里得到这个过程,但它太奇怪了,我怀疑自己。下面看评论,有什么乱七八糟的地方。 DECLARE srcFile BFILE := BFILENAME('SOME_DIR',
我正在尝试将图像加载到 Oracle 多媒体数据库中。我的 OrdImage.loadDataFromFile() 方法有问题,它会抛出 SQLException java.sql.SQLExcept
我一直在尝试在 C++ VS 2013 中使用 SFML 输出图像,但是当我使用 loadFromFile 时,它没有显示任何内容,我检查了工作目录,它是项目目录,图像在其中的一个文件。这是代码:
我有以下代码: #include #include int main(int argc, char* argv[]) { sf::RenderWindow window(sf::Video
我正在学习使用 SFML 来制作一个小游戏,到目前为止,我已经创建了一个窗口并乱搞了它的设置,并设置了一个绘制循环和事件处理程序。 一旦我尝试使用以下代码添加我的第一个纹理,问题就开始了: #incl
我正在使用 SFML 2.2 和 Visual Studio Express 2013。 我只是想加载纹理并将其应用到 Sprite ,就像在 http://www.sfml-dev.org/tuto
在 32 位、8GB 内存的 Win 10 系统上编译。 尝试使用 Tstringlist.Loadfromfile 加载 150Mb ASCII 文件会出现“内存不足错误”,任务管理器报告已使用 1
最近我一直在测试 SFML 2.3 中的一些功能,并且我开始熟悉 C++。尝试后,我决定尝试将文本添加到程序中,使用 sf::Text 和 sf::Font。 这样做之后,我在运行该程序时遇到了问题,
我在 xcode4 中使用 sfml 2.1。 ballSpriteSheet.png 位于项目文件夹中。它使用完整的文件路径加载。为什么文件不会按写入的方式加载?如果写的不可能,你能至少设置一个相对
我有这个资源类,它为我保存我的资源(只是字体)。我调用 initialise() 来加载资源,然后我做正常的程序流程,在我退出程序之前调用 cleanUp()。这一切都很完美。 这是类的代码。资源.h
我试图在 SFML 中加载纹理,但它不起作用。似乎程序甚至不知道 JPG 的存在。 sf::Texture table; if (!table.loadFromFile("pool-table
我正在对标准 VCL TImage 控件和各种其他第三方替代方案的性能进行一些比较。我使用 GetTickCount 来测量加载图像所需的时间。实际上,大约需要 4 秒,但是 LoadFromFile
在我打开这个帖子之前我做了一个搜索以防止重复问题,我发现了一些类似的问题,但它们有点老了。 我按照官方指南的建议配置了 SFML(代码块),我什至编译了测试代码并实际工作,但是当我尝试使用纹理或图像时
当我开始游戏时,fps 大约是 60,但按住“W”按钮时,我的 fps 下降到 30。松开那个按钮时,它再次变为 60。发生这种情况是因为代码行:模型->加载("img/characters.png"
我有一个 Delphi 2006 应用程序,我正在添加代码来处理一些生成的 CSV 数据文件。 TStringList.LoadFromFile 给出了奇怪的结果,我刚刚发现这些文件是 UTF-16
我是一名优秀的程序员,十分优秀!