当我想在 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 方面高效?
您可以使用
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 中一样!
这里有一些有用的参考:
免责声明:根据我对 C 的
open
函数如何工作的了解,我相信这 应该 可以解决问题。
import mmap
def read_large_file(filename):
with open(filename, "rb") as f:
# Map the entire file into memory
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as mm:
# Access the file contents via the memory map
file_contents = mm[:]
return file_contents
# Usage
file_contents = read_large_file("file.bin")