Python等效于使用管道将文件输出到Perl中的gzip的管道文件

问题描述 投票:10回答:4

我需要弄清楚如何用Python将文件输出写入压缩文件,类似于下面的两层代码:

open ZIPPED, "| gzip -c > zipped.gz";
print ZIPPED "Hello world\n";

[在Perl中,它使用Unix gzip将您打印到ZIPPED文件句柄的所有内容压缩为文件“ zipped.gz”。

我知道如何使用“ import gzip”在Python中执行以下操作:

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

但是,那太慢了。根据探查器,使用该方法占用了我90%的运行时间,因为我正在将200GB的未压缩数据写入各种输出文件。我知道文件系统可能是这里问题的一部分,但是我想通过使用Unix / Linux压缩来排除它。部分原因是因为我听说使用同一模块进行解压缩也很慢。

python gzip pipe compression filehandle
4个回答
10
投票

ChristopheD建议使用subprocess module是对该问题的适当答案。但是,对我来说,尚不清楚它将解决您的性能问题。您必须测量新代码的性能才能确定。

要转换示例代码:

import subprocess

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

由于需要向子流程发送大量数据,因此应考虑使用Popen对象的stdin属性。例如:

stdin

您可能还会发现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 上的讨论会很有帮助。


6
投票

尝试这样的事情:

this question

2
投票

使用from subprocess import Popen, PIPE f = open('zipped.gz', 'w') pipe = Popen('gzip', stdin=PIPE, stdout=f) pipe.communicate('Hello world\n') f.close() 是官方的单向方法,其他任何纯python方法都不太可能更快。尤其如此,因为数据大小排除了内存中的选项。最可能的最快方法是将整个文件写入磁盘,然后使用gzip module对该文件调用gz


0
投票

除了subprocess的答案外,我想通过禁用外壳程序选项@srgerg来应用相同的方法,该方法也可以在@Moishe Lettvin的答案上进行,并建议在(shell=False)上使用。

https://stackoverflow.com/a/3172488/2402577

请不要以为我原来是将import subprocess def zip(): f = open("zipped.gz", "w") p1 = subprocess.Popen(["echo", "Hello World"], stdout=subprocess.PIPE) p2 = subprocess.Popen(["gzip", "-9c"], stdin=p1.stdout, stdout=f) p1.stdout.close() p2.communicate() f.close() p1的输出用作:

git diff

© www.soinside.com 2019 - 2024. All rights reserved.