如何在UNIX中解压缩zlib数据?


106

我已经在Python中创建了zlib压缩的数据,如下所示:

import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
    f.write(z)

(或单行中壳:echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data

现在,我想解压缩shell中的数据。既不zcat也不uncompress工作:

$ cat /tmp/data | gzip -d -
gzip: stdin: not in gzip format

$ zcat /tmp/data 
gzip: /tmp/data.gz: not in gzip format

$ cat /tmp/data | uncompress -
gzip: stdin: not in gzip format

看来我已经创建了类似gzip的文件,但是没有任何标题。不幸的是,我在gzip手册页中看不到任何解压缩此类原始数据的选项,并且zlib软件包不包含任何可执行实用程序。

是否有用于解压缩原始zlib数据的实用程序?


Answers:


140

如果没有,或者想要使用或其他工具,也可以使用标准的 + 解压缩。诀窍是在gzip魔术数字和compress方法之前添加来自的实际数据:
zlib.compress

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out

编辑:
@ d0sboots评论:对于RAW Deflate数据,您需要再添加2个空字节:
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

SO上的Q问题提供了有关此方法的更多信息。那里的答案表明也有一个8字节的页脚。

用户@ Vitali-Kushner和@ mark-bessey甚至在文件被截断的情况下也报告了成功,因此gzip页脚似乎并不是严格要求的。

@ tobias-kienzler建议为此功能:
zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - $@ |gzip -dc)


gzip不起作用,但是zlib-flate起作用(pdf页面内容流)。
Daneel S. Yaitskov '17

69

用户@tino在OpenSSL答案下方评论,但我认为这应该分开:

zlib-flate -uncompress < FILE

我尝试了这个,对我有用。

zlib-flate可以在软件包qpdf中找到(根据其他答案中的注释,在Debian Squeeze和Fedora 23中)


3
与其他答案相反,此答案适用于
OSX。– polym

2
@polym,如何在macOS上zlib-flate 安装?我什么都看不到。
通配符

4
@Wildcard很抱歉收到您的回复。我认为它是随qpdf上面brew提到的注释安装的软件包一起提供的-或查看此答案的最后一句话:)。另外,qpdf这真的很酷,如果有时间的话,也可以看看!
polym

brew install qpdf,然后上面列出的命令:-)谢谢!
费尔南多·加布里埃利

60

我找到了一种解决方案(可能的一种),它正在使用openssl

$ openssl zlib -d < /tmp/data

要么

$ openssl zlib -d -in /tmp/data

*注意:zlib功能显然在最新的opensl版本> = 1.0.0中可用(必须使用zlib或zlib-dynamic选项配置/构建OpenSSL,后者是默认选项)


25
在Debian Squeeze(具有OpenSSL 0.9.8)上,包含zlib-flateqpdf软件包中。可以像这样使用zlib-flate -uncompress < FILE
Tino 2012年

7
zlib已从最新版本的OpenSSL中删除,因此此提示对@Tino很有帮助
Alexandr

1
谢谢。与使用“ gzip”的答案相比,此解决方案在解压缩短输入文件方面提供了更好的体验(“ openssl”尽可能地被解压缩,而“ gzip”中止打印“意外的文件结尾”)。
丹尼尔·K

2
@Tino这应该是一个单独的答案
Catskul

1
@Tino,也可以通过Fedora 23上的qpdf软件包获得。Alexandr Kurilin,zlib仍在1.0.2d-fips中可用。
maxschlepzig

28

我建议pigz马克·阿德勒,zlib压缩库的合着者。执行pigz以查看可用的标志。

您会注意到:

-z --zlib Compress to zlib (.zz) instead of gzip format.

您可以使用-d标志解压缩:

-d --decompress --uncompress Decompress the compressed input.

假设一个名为“ test”的文件:

  • pigz -z test -创建一个名为test.zz的zlib压缩文件
  • pigz -d -z test.zz -将test.zz转换为解压缩的测试文件

在OSX上,您可以执行 brew install pigz


7
好发现!看起来它可以单独检测zlib文件,因此unpigz test.zz也可以正常工作。
斯特凡Chazelas

没有解压缩我的数据。
Cyber​​nard

1
@cybernard也许您没有zlib文件。检查与:$>file hello.txt.zz hello.txt.zz: zlib compressed data
snodnipper

11

zlib实现gzip使用的压缩,但不实现文件格式。相反,您应该使用本身使用的gzip模块zlib

import gzip
s = '...'
with gzip.open('/tmp/data', 'w') as f:
    f.write(s)

好的,但是我的情况是我已经创建了成千上万的文件,所以.. :)

1
所以...您的文件不完整。如果您仍然没有原始数据,则可能需要使用进行解压缩,然后使用zlib进行重新压缩gzip
Greg Hewgill 2011年

6
@mykhal,为什么在检查是否可以真正解压缩文件之前创建十万/十万个文件?

3
harpyon,我可以解压缩它们,我只是想知道可以使用哪些较少或更多的通用性或zgip设置,如果我不想再次在python中使用它

3

这可以做到:

import glob
import zlib
import sys

for filename in sys.argv:
    with open(filename, 'rb') as compressed:
        with open(filename + '-decompressed', 'wb') as expanded:
            data = zlib.decompress(compressed.read())
            expanded.write(data)

然后像这样运行它:

$ python expander.py data/*

谢谢,我知道zlib.decompress。大概我会用一些步行功能。我不确定shell是否可以使用glob通配符处理我的大量文件:)

使用shell file命令,由扩展程序创建的文件仍对我来说是“ zlib压缩数据” ?那个怎么样?
K.-Michael Aye

即使使用伪造的标头,nope对我也不起作用。
Cyber​​nard

3

Mark Adler本人zpipe.c 在这里找到的示例程序(与zlib库的源分发一起提供)对于使用原始zlib数据的这些情况非常有用。编译cc -o zpipe zpipe.c -lz并解压缩:zpipe -d < raw.zlib > decompressed。它也可以在没有-d标志的情况下进行压缩。


2

在完全兼容POSIX的UNIX(已正式认证!)的macOS上,OpenSSLzlib提供支持,也没有任何支持,zlib-flate尽管第一个解决方案与所有Python解决方案一样有效,但第一个解决方案要求ZIP数据位于文件中其他所有解决方案都会迫使您创建Python脚本。

这是一个基于Perl的解决方案,可以用作命令行单行代码,通过STDIN管道获取输入,并且可以与新安装的macOS一起使用:

cat file.compressed | perl -e 'use Compress::Raw::Zlib;my $d=new Compress::Raw::Zlib::Inflate();my $o;undef $/;$d->inflate(<>,$o);print $o;'

格式更好,Perl脚本如下所示:

use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;

1

您可以使用它与zlib一起压缩:

openssl enc -z -none -e < /file/to/deflate

然后缩小:

openssl enc -z -none -d < /file/to/deflate

4
提供unknown option '-z'Ubuntu 16.04和OpenSSL 1.0.2g 1 Mar 2016
Tino,

2
在Mac上出现相同的错误
K.-Michael Aye

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.