不是逐行读取文件
Posted
技术标签:
【中文标题】不是逐行读取文件【英文标题】:Reading from a file not line-by-line 【发布时间】:2009-06-26 12:52:54 【问题描述】:将QTextStream
分配给QFile
并逐行读取它很容易并且工作正常,但我想知道是否可以通过首先将文件存储在内存中然后逐行处理来提高性能-线。
使用来自 sysinternals 的FileMon,我遇到了以 16KB 的块读取文件,并且由于我要处理的文件不是那么大(~2MB,但很多!),将它们加载到内存中尝试是一件好事。
任何想法我该怎么做? QFile
是从QIODevice
继承而来的,这让我可以将ReadAll()
它变成QByteArray
,但是如何继续并把它分成几行呢?
【问题讨论】:
【参考方案1】:QTextStream 有一个 ReadAll 函数:
http://doc.qt.io/qt-4.8/qtextstream.html#readAll
确定这就是你所需要的吗?
或者您可以将所有内容读入QByteArray,QTextStream 可以将其作为输入而不是 QFile。
【讨论】:
谢谢!我没有意识到 QTextStream 可以使用 QByteArray。这完全解决了它。【参考方案2】:小心。有很多影响需要考虑。
对于所涉及的字符串处理(或您对文件执行的任何操作),如果文件缓冲是合理的,那么从内存执行和逐行执行文件之间可能没有性能差异。
实际上调用您的操作系统进行低级读取是非常昂贵的。这就是我们缓冲 I/O 的原因。对于小的 I/O 大小,调用的开销占主导地位。因此,一次读取 64 个字节的效率可能是一次读取 256 个字节的 1/4。 (我在这里说的是 read(),而不是 fgets() 或 fread() 两者都是缓冲的。)
在某个时间点,物理 I/O 所需的时间开始占主导地位,当更大的缓冲区的性能没有增加太多时,您已经找到了您的缓冲区大小。非常旧的数据点:7MHz Amiga 500、100MB SCSI 硬盘(A590+Quantum):我的 I/O 性能真的只有在 256KB 缓冲区大小时才达到最大值。与处理器相比,该磁盘非常快!!! (计算机只有 3MB 的 RAM。256KB 是一个很大的缓冲区!)
但是,您可能拥有太多的好东西。一旦您的文件在内存中,操作系统可以在空闲时将该文件分页回磁盘。如果这样做,您将失去缓冲的任何好处。如果您将缓冲区设置得太大,那么这可能会在某些负载情况下发生,并且您的性能会下降。因此,请仔细考虑您的运行时环境,并在需要时限制内存占用。
另一种方法是使用 mmap() 将文件映射到内存中。现在操作系统不会将您的文件分页 - 相反,它根本不会分页,或者如果它需要内存,它将丢弃缓存在核心中的任何文件。但它不需要写任何东西来交换空间——它有可用的文件。但是,我不确定这是否会带来更好的性能,因为以大块执行 I/O 仍然更好,并且虚拟内存倾向于以页面大小的块移动内容。一些内存管理器可能会在块中移动页面以增加 I/O 带宽和预取页面方面做得不错。但我并没有真正详细研究过这个。
首先让您的程序正常运行。然后优化。
【讨论】:
感谢您的评论。当然我已经让它工作了,这就是为什么考虑尝试优化。 mmap() 不可移植。【参考方案3】:只要不每次读取单行时打开和关闭文件,先读入整个文件或边读边处理应该没有性能差异(除非处理部分更快当您有整个文件可以使用时)。如果你仔细想想,这两种方式实际上都是在做同样的事情(读取整个文件一次)。
【讨论】:
【参考方案4】:你可以
QTextStream ( QIODevice * device )
QTextStream 类提供了一个方便的读取接口和 写文字。
QTextStream 可以对 QIODevice、QByteArray 或 QString 进行操作。 使用 QTextStream 的流式操作符,您可以方便地阅读和 写出单词、线条和数字。
【讨论】:
以上是关于不是逐行读取文件的主要内容,如果未能解决你的问题,请参考以下文章