目标
读取大小为1.3GB的大量二进制文件并更改某些位,然后将其写回单独的文件(无法修改原始文件)。
方式
当我读入二进制文件时,它被存储在一个以十六进制格式编码的大量字符串中,这是不可变的,因为我使用的是python。
我的算法遍历整个文件,并在列表中存储需要修改的字符串的所有索引。问题是字符串中的所有索引都需要修改为相同的值。由于不变性,我无法做到这一点。我无法将其转换为字符列表,因为这会破坏我的内存限制并花费大量时间。可行的方法是将它存储在一个单独的字符串中,但由于不可变的性质,我必须制作大量的字符串对象并继续与它们连接。
我使用了来自https://waymoot.org/home/python_string/的一些想法,但它并没有给我一个好的表现。任何想法,目标是将现有的超长字符串完全复制到另一个,除了由索引列表中的值确定的某些占位符?
答案 0 :(得分:5)
所以,说实话,你不应该把你的文件读成字符串。除了你实际改变的字节之外,你不应该特别写任何东西。 这只是浪费资源,因为你似乎只是在文件中线性阅读,注意到需要修改的地方。
在所有具有某种级别的mmap支持的操作系统上(即Unix,其中包括Linux,OS X,* BSD和其他操作系统,如Windows),您可以使用Python's mmap
模块打开读取的文件/ write模式,扫描并对其进行编辑,无需将其完全加载到RAM中,然后将其写回。愚蠢的例子,将所有12值字节转换为位置相关的东西:
注意:此代码是我的,而不是MIT许可的。它用于文本增强目的,因此由CC-by-SA涵盖。感谢SE让这个愚蠢的陈述成为必要。
import mmap
with open("infilename", "r") as in_f:
in_view = mmap.mmap(in_f.fileno(), 0) ##length = 0: complete file mapping
length = in_view.size()
with open("outfilename", "w") as out_f
out_view = mmap.mmap(out_f.fileno(), length)
for i in range(length):
if in_view[i] == 12:
out_view[i] = in_view[i] + i % 10
else:
out_view[i] = in_view[i]
答案 1 :(得分:0)
如何切片,修改每个切片,将其写回磁盘,然后再转到下一个切片?磁盘太密集了?