2011-11-28 72 views
9

我需要想出如何文件輸出寫入Python中的壓縮文件,類似於下面的兩襯墊在Perl gzip壓縮,它使用Unix gzip將打印到ZIPPED文件句柄的任何內容壓縮到文件「zipped.gz」。Python的等效管道文件輸出到使用管

我知道如何使用「進口的gzip」要做到這一點在Python這樣的:

import gzip 
zipped = gzip.open("zipped.gz", 'wb') 
zipped.write("Hello world\n") 

然而,這是極其緩慢。根據探查器,使用該方法佔用了我運行時間的90%,因爲我正在向各種輸出文件寫入200GB的未壓縮數據。我知道文件系統可能是這個問題的一部分,但我想通過使用Unix/Linux壓縮來解決它。這部分是因爲我聽說使用這個模塊進行解壓縮也很慢。

+1

你需要它在純Python做,或者你可以解決一個呼叫轉換成二進制的文件系統(在Python中,你會使用的子模塊)? – ChristopheD

+0

由於純Python方法太慢,我寧願不要用Python來完成它。 – bu11d0zer

+0

你是否從200GB的未壓縮數據的shell中運行gzip程序?我希望在90-100%的CPU利用率下花費相當多的掛鐘時間 - 在我的Windows機器上,它每GB運行約1分鐘,而Python gzip模塊每GB大約需要2分鐘。 – Dave

回答

10

ChristopheD建議使用subprocess module是對這個問題的適當答案。但是,我不清楚它會解決您的性能問題。您必須測量新代碼的性能。由於需要大量的數據發送到子過程中,你應該考慮使用POPEN對象的屬性stdin

import subprocess 

p = subprocess.Popen("gzip -c > zipped.gz", shell=True, stdin=subprocess.PIPE) 
p.communicate("Hello World\n") 

要轉換的示例代碼。例如:

import subprocess 

p = subprocess.Popen("gzip -c > zipped.gz", shell=True, stdin=subprocess.PIPE) 
p.stdin.write("Some data") 

# Write more data here... 

p.communicate() # Finish writing data and wait for subprocess to finish 

您也可以在this question有幫助找到的討論。

+0

我驗證了這種方法在1GB高度可壓縮文件上的速度提高了33%。與gzip.open相比,這是一個不錯的改進。下面是我用來測試它的代碼: 進口子文本= 「fjlaskfjioewru oijf alksfjlkqs JR jweqoirjwoiefjlkadsfj afjf \ n」 個 爲i的x範圍(1,25): 文本+ =文本 P = subprocess.Popen( 「gzip -c> zipped.gz」,shell = True,stdin = subprocess.PIPE)' p.stdin.write(text) p.communicate() gzip的時間。打開: 12.109u 1.194s 0:13.37 99.4%0 + 0K 0 + 0io 0pf +0瓦特 時間爲上述代碼: 8.379u 2.602s 0:10.17 107.8%0 + 0K 0 + 0io 0pf +0瓦特 – bu11d0zer

+0

這對我的問題是一個很好和完整的答案。謝謝。 – bu11d0zer

+0

一定要接受你最喜歡的答案:-)。我們都喜歡額外的代表。 – Dave

2

使用gzip module是官方的一種方法,它不太可能會使任何其他純Python方法變得更快。這是尤其如此,因爲您的數據的大小排除了內存中的選項。最有可能的最快方法是將完整文件寫入磁盤,並使用subprocess在該文件上調用gz

4

嘗試這樣:

from subprocess import Popen, PIPE 
f = open('zipped.gz', 'w') 
pipe = Popen('gzip', stdin=PIPE, stdout=f) 
pipe.communicate('Hello world\n') 
f.close() 
+0

這個答案也很好,工作得很好。 – bu11d0zer