将(大量)零写入二进制文件

时间:2017-10-09 12:44:00

标签: python file binary

这可能是一个愚蠢的问题,但我无法找到合适的答案。我想存储(不要问为什么)(2000, 2000, 2000)零的二进制表示形式的磁盘,二进制格式。实现这一目标的传统方法是:

with open('myfile', 'wb') as f:
    f.write('\0' * 4 * 2000 * 2000 * 2000)  # 4 bytes = float32

但这意味着要创建一个非常大的字符串,这根本不是必需的。我知道另外两个选择:

  • 迭代元素并一次存储一个字节(非常慢)

  • 创建一个numpy数组并将其刷新到磁盘(与上面示例中的字符串创建一样昂贵的内存)

我正在寻找像write(char, ntimes)(因为它存在于C和其他语言中)以C速度复制到磁盘char ntimes而不是Python循环速度的东西,无需在内存上创建如此大的数组。

5 个答案:

答案 0 :(得分:1)

这将是使用numpy's memmap:

从Python填充文件的有效答案
shape = (2000, 2000, 2000) # or just (2000 * 2000 * 2000,)
fp = np.memmap(filename, dtype='float32', mode='w+', shape=shape)
fp[...] = 0

答案 1 :(得分:1)

我不知道为什么你会对“Python的循环速度”这么大惊小怪,但写作的方式是

for i in range(2000 * 2000):
     f.write('\0' * 4 * 2000)  # 4 bytes = float32

将告诉操作系统写入8000个0字节。在write返回后,在下一个循环运行中再次调用它。

可能是循环的执行速度比在C中稍慢,但这绝对不会产生影响。

如果可以使用稀疏文件,您也可以寻找所需文件大小的位置,然后截断文件。

答案 2 :(得分:0)

要编写零,有一个很好的黑客:以读写方式打开文件,寻找偏移减1,然后再写零。

这也用零填充文件的开头:

mega_size = 100000
with open("zeros.bin","wb+") as f:
    f.seek(mega_size-1)
    f.write(bytearray(1))

答案 3 :(得分:0)

原始海报无法说明为什么确实需要使用python来完成。因此,这是一个小的Shell脚本命令,它执行相同的操作,但速度可能会稍快一些。假设OP位于类似Unix的系统(Linux / Mac)上

定义:bs(块大小)= 2000 * 2000,计数= 4 * 2000 if(输入文件)是一个特殊的“零产生”设备。 (输出文件)的of必须指定为wel。

dd bs=4000000 count=8000  if=/dev/zero of=/Users/me/thirtygig

在我的计算机(ssd)上,这大约需要110秒: 在108.435354秒(295106705字节/秒)中传输了32000000000字节

您始终可以从python调用此小shell命令。

为了进行比较,@ glglgl小python脚本在303秒内在同一台计算机上运行,​​因此只慢了3倍,这可能足够快。

答案 4 :(得分:-2)

数据量约为30G字节。 显然,在将文件放入文件之前,它不能存储在RAM中。

也许最好的方法是使用磁盘集群大小的缓冲区(4k,128k,512k?)