我试图在 Bash 中复制这个 bash 命令,它返回每个压缩 50MB 的文件。
split -b 50m "file.dat.gz" "file.dat.gz.part-"
Run Code Online (Sandbox Code Playgroud)
我在 python 等价物上的尝试
import gzip
infile_name = "file.dat.gz"
chunk = 50*1024*1024 # 50MB
with gzip.open(infile_name, 'rb') as infile:
for n, raw_bytes in enumerate(iter(lambda: infile.read(slice), '')):
print(n, chunk)
with gzip.open('{}.part-{}'.format(infile_name[:-3], n), 'wb') as outfile:
outfile.write(raw_bytes)
Run Code Online (Sandbox Code Playgroud)
这将每个 gzip 返回 15MB。当我用枪压缩文件时,它们每个都是 50MB。
如何在 python 中拆分 gzipped 文件,以便在压缩前每个拆分的文件每个 50MB?
我不相信这split会像你想象的那样起作用。它不会将 gzip 文件分割成更小的 gzip 文件。即,您无法对其创建的单个文件调用gunzip。它实际上将数据分解成更小的块,如果你想压缩它,你必须首先将所有的块连接在一起。因此,为了用 Python 模拟实际行为,我们会这样做:
infile_name = "file.dat.gz"
chunk = 50*1024*1024 # 50MB
with open(infile_name, 'rb') as infile:
for n, raw_bytes in enumerate(iter(lambda: infile.read(chunk), b'')):
print(n, chunk)
with open('{}.part-{}'.format(infile_name[:-3], n), 'wb') as outfile:
outfile.write(raw_bytes)
Run Code Online (Sandbox Code Playgroud)
实际上,我们会读取多个较小的输入块,以使一个输出块使用更少的内存。
我们也许能够将文件分解成更小的文件,我们可以单独对它们进行压缩,并且仍然达到我们的目标大小。使用bytesIO流之类的东西,我们可以枪压缩文件并将其 gzip 到该内存流中,直到达到目标大小,然后将其写出并启动一个新bytesIO流。
对于压缩数据,您必须测量输出的大小,而不是输入的大小,因为我们无法预测数据的压缩效果。