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

时间:2011-11-28 21:54:27

标签: python gzip pipe compression filehandle

我需要弄清楚如何将文件输出写入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压缩来排除它。这部分是因为我听说使用同一模块进行解压缩也很慢。

5 个答案:

答案 0 :(得分: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属性。例如:

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上找到有用的讨论。

答案 1 :(得分:5)

尝试这样的事情:

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

答案 2 :(得分:2)

使用 gzip module 是官方的单向操作,并且任何其他纯python方法都不太可能更快。这尤其正确,因为数据大小排除了内存中的选项。最有可能的是,最快的方法是将完整文件写入磁盘并使用subprocess在该文件上调用 gz

答案 3 :(得分:0)

除了shell=False的答案之外,我想通过禁用外壳选项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() 来应用相同的方法,这也对@Moishe Lettvin的答案也做了建议,并建议在(https://stackoverflow.com/a/3172488/2402577)上使用。

p1

请注意,最初我不是将git diff的以下p1 = subprocess.Popen(["git", "diff"], stdout=subprocess.PIPE)输出用作:

import numpy as np import mayavi.mlab as mlab # creating volume that increases in value img3d = np.arange(20) img3d = np.expand_dims(img3d, axis=1) img3d = np.expand_dims(img3d, axis=2) img3d = np.tile(img3d, (1, 20, 20)) fig = mlab.figure() src = mlab.pipeline.scalar_field(img3d) # Plotting two cut planes cp2 = mlab.pipeline.scalar_cut_plane(src, plane_orientation='y_axes') cp2.implicit_plane.widget.enabled = False cp3 = mlab.pipeline.scalar_cut_plane(src, plane_orientation='z_axes') cp3.implicit_plane.widget.enabled = False mlab.view(azimuth=50, elevation=None) mlab.outline() mlab.show()

答案 4 :(得分:0)

在比较速度时,请确保使用相同的压缩级别。默认情况下,Linux gzip使用6级,而python使用9级。我在Python 3.6.8中使用gzip 1.5版对此进行了测试,压缩了来自MySQL转储的600MB数据。使用默认设置:

python模块需要9.24秒的时间,并生成文件47.1 MB
子进程gzip耗时8.61秒,使文件48.5 MB

将其更改为6级,以便它们匹配:
python模块耗时8.09秒,使文件48.6 MB
子进程gzip耗时8.55秒,使文件48.5 MB

overflow-x:hidden;