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

时间:2016-04-04 01:58:26

标签: python gzip

以下代码段打开一个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

有没有办法将gzip风格的伪文件句柄传递给通过subprocess运行的进程,或者是否真的没有办法编写非压缩文件,然后返回并压缩它?

1 个答案:

答案 0 :(得分: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)

这个想法是在子进程完成之前延迟附加压缩数据:

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

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