2017-07-22 22 views
4

我想在Bash中複製這個bash命令,它返回每個文件gzip每個50MB。在Python中分割相當於gzip文件

split -b 50m "file.dat.gz" "file.dat.gz.part-" 

我在蟒蛇相當於

import gzip 
infile = "file.dat.gz" 
slice = 50*1024*1024 # 50MB 
with gzip.open(infile, 'rb') as inf: 
    for i, ch in enumerate(iter(lambda: inf.read(slice), "")): 
    print(i, slice) 
    with gzip.open('{}.part-{}'.format(infile[:-3], i), 'wb') as outp: 
     outp.write(ch) 

這將返回15MB每個gzip壓縮的嘗試。當我對這些文件進行壓縮時,它們每個都是50MB。

如何分割python中的gzip文件,以便在gunzipping之前每個文件分割爲50MB?

回答

1

我不認爲split按照您認爲的方式工作。它不會將gzip文件分割成更小的gzip文件。即你不能對它創建的單個文件調用gunzip。它實際上將數據分解爲更小的塊,如果你想對它進行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) 

在現實中,我們讀到多個較小的輸入塊,使一個輸出大塊使用較少的內存。

我們可能會將文件分割成更小的文件,我們可以單獨進行gunzip,並且仍然可以製作目標大小。使用類似bytesIO流的東西,我們可以對該文件進行gunzip壓縮,然後將其壓縮到該內存流中,直到達到目標大小,然後將其寫出並開始新的bytesIO流。

對於壓縮數據,您必須測量輸出的大小,而不是輸入的大小,因爲我們無法預測數據的壓縮程度。