簡體   English   中英

Python管道到`gzip.open`文件句柄

[英]Python piping to `gzip.open` filehandle

以下代碼段將打開一個gzip文件句柄並向其中寫入一行,然后以附加模式再次打開它,並將子進程的stdout重定向到gzip壓縮的文件句柄。

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

$ gunzip file.txt.gz

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

是否可以通過subprocess進程將gzip風格的偽文件句柄傳遞給進程運行,或者真的沒有其他方法可以寫未壓縮的文件然后返回並對其進行壓縮?

如果您搜索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)

這個想法是將壓縮數據的添加延遲到子流程完成之后:

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

在Python 3.5中添加了subprocess.run()函數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM