2016-04-04 87 views
0

下面的代碼片斷打開一個gzip文件句柄,並向它寫入一行,然後以append模式再次打開它,並將子進程的stdout重定向到gzip文件句柄。Python管道到`gzip.open`文件句柄

import gzip 
import subprocess 

with gzip.open("./file.txt.gz", "w") as fh: 
    fh.write("this is the first line\n") 

with gzip.open("./file.txt.gz", "a") as fh: 
    subprocess.call("echo this is the second line", shell=True, stdout=fh) 

當我嘗試解壓縮文件,看看我寫它,我得到以下錯誤

$ gunzip file.txt.gz 
gzip: file.txt.gz: decompression OK, trailing garbage ignored 

解壓後的內容只包括第一線的

$ cat file.txt 
this is the first line 

當我使用相同的文件句柄來寫一行和作爲一個進程的輸出時,我得到一個甚至不被gunzip識別的文件。

import gzip 
import subprocess 

with gzip.open("./file.txt.gz", "w") as fh: 
    fh.write("this is the first line\n") 
    subprocess.call("echo this is the second line", shell=True, stdout=fh) 

例如,產生的文件不能是gunzip'd。

$ gunzip file.txt.gz 

gzip: file.txt.gz: not in gzip format 

是否有通過subprocess傳遞一個gzip味僞文件句柄到一個進程運行方式或者是真的沒有替代書寫非壓縮文件,然後回去和壓縮呢?

回答

1

如果你搜索StackOverflow,你會發現這個問題偶爾會出現,但答案並不總是直接實現。它們的要點似乎是subprocess.call()無法通過僞文件句柄 - 它必須是真實的。標準的解決方法似乎是使用subprocess.Popen()

但是,這裏有一個簡單的妥協我的工作了:

import gzip 
import subprocess 

with gzip.open("file.txt.gz", "wt") as handle: 
    handle.write("this is the first line\n") 

completed = subprocess.run("echo 'this is the second line'", shell=True, stdout=subprocess.PIPE, universal_newlines=True) 

with gzip.open("file.txt.gz", "at") as handle: 
    handle.write(completed.stdout) 

的想法是拖延,直到子進程完成後附加的壓縮數據:Python中加入

> gzcat file.txt.gz 
this is the first line 
this is the second line 
> 

subprocess.run()功能3.5