【问题标题】:read a large file without memory reallocation读取没有内存重新分配的大文件
【发布时间】:2017-06-28 23:04:46
【问题描述】:

当我想在 python 中读取内存中的二进制文件时,我只是这样做:

with open("file.bin","rb") as f:
    contents = f.read()

使用“合理”大小的文件,它是完美的,但是当文件很大时(例如,1Gb 或更大),在监控进程时,我们注意到内存先增加然后缩小,然后再增加,......可能是效果realloc 在幕后,当原始内存块太小而无法容纳文件时。

多次完成,这个realloc + memmove 操作占用大量CPU时间。在 C 语言中,我不会遇到问题,因为我会将正确分配的缓冲区传递给 fread (但在这里我不能,因为 bytes 对象是不可变的,所以我不能预先分配)。

当然,我可以像这样逐块阅读它:

with open("file.bin","rb") as f:
    while True:
        contents = f.read(CHUNK_SIZE)
        if contents:
            chunks.append(contents)
        else:
             break

但是我必须 join 字节块,但这也会在某些时候占用两倍所需的内存,而且我可能负担不起。

有没有一种方法可以读取缓冲区中的大二进制文件,只分配一个大内存,并且在 CPU 方面高效?

【问题讨论】:

标签: python memory


【解决方案1】:

您可以使用 os.open 方法,它基本上是 POSIX 系统调用 open 的包装器。

import os
fd = os.open("file.bin", os.O_RDONLY | os.O_BINARY)

这会以rb 模式打开文件。

os.open 返回一个没有read 方法的文件描述符。您必须一次读取n 字节:

data = os.read(fd, 100)

完成后,使用os.close 关闭文件:

os.close(fd)

您在 Python 中读取文件就像在 C 中一样!

这里有几个有用的参考资料:

  1. Official docs
  2. Library Reference

免责声明:根据我对 C 的 open 函数如何工作的了解,我相信这个应该可以解决问题。

【讨论】:

  • 错字:这是O_BINARY。我的错。
  • 不错。所以我可以通过os.read(fd,os.path.getsize(filename)) 一口气读完。让我测试一下。
  • 嗯,我不确定如果你一口气读完会发生什么。但值得一试。
  • 如果它没有按预期工作,请告诉我,我将删除我的答案。 :)
  • 我想我可以对f.read(os.path.getsize(filename)) 做同样的事情,我有点笨......但无论如何,非缓冲方面可能会更快。我会及时通知你。
猜你喜欢
  • 2013-02-24
  • 2020-01-31
  • 2018-11-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 2010-12-24
  • 2020-01-26
  • 2018-10-15
相关资源
最近更新 更多