Deflate命令行工具

我正在寻找DEFLATEalgorithm的命令行包装器。

我有一个使用DEFLATE压缩的文件(git blob),我想解压缩它。 gzip命令似乎没有直接使用DEFLATEalgorithm的选项,而不是gzip格式。

理想情况下,我正在寻找一个标准的Unix / Linux工具,可以做到这一点。

编辑:这是我尝试使用gzip的问题时得到的输出:

$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip gzip: stdin: not in gzip format 

如果我理解Marc van Kempen提到的Wikipedia文章中的提示,可以直接使用zlib中的 puff.c

这是一个小例子:

 #include <assert.h> #include <string.h> #include "puff.h" int main( int argc, char **argv ) { unsigned char dest[ 5 ]; unsigned long destlen = 4; const unsigned char *source = "\x4B\x2C\x4E\x49\x03\x00"; unsigned long sourcelen = 6; assert( puff( dest, &destlen, source, &sourcelen ) == 0 ); dest[ 4 ] = '\0'; assert( strcmp( dest, "asdf" ) == 0 ); } 

类似下面的内容将打印原始内容,包括“$ type $ length \ 0”标题:

 perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \ < .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577 

你可以用OpenSSL命令行工具来做到这一点:

 openssl zlib -d < $IN > $OUT 

不幸的是,至less在Ubuntu上, zlib子命令在默认的构buildconfiguration( --no-zlib --no-zlib-dynamic )中被禁用,所以你需要从源代码编译openssl来使用它。 但是它在Arch上默认是启用的,例如。

编辑:似乎arch不再支持zlib命令。 这个答案可能不再有用:(

pythonic单线:

 $> python -c "import zlib,sys;print \ repr(zlib.decompress(sys.stdin.read()))" < $IN 

你可以使用zlib-flate,就像这样:

 cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \ | zlib-flate -uncompress; echo 

它在我的机器上是默认的,但它是qpdf - tools for and transforming and inspecting PDF files的一部分qpdf - tools for and transforming and inspecting PDF files如果你需要安装。

我在命令的末尾popup了一个echo ,因为以这种方式读取输出比较容易。

尝试以下命令:

 printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip 

不需要外部工具。

来源: 如何在UNIX中解压缩zlib数据? 在unix SE

这里是一个ruby单行(CD .git /第一,并确定任何对象的path):

 ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208 

这是一个在Python中打开一个提交对象的例子:

 $ git show commit 0972d7651ff85bedf464fba868c2ef434543916a # all the junk in my commit... $ python >>> import zlib >>> file = open(".git/objects/09/72d7651ff85bedf464fba868c2ef434543916a") >>> data = file.read() >>> print data # binary garbage >>> unzipped_data = zlib.decompress(data) >>> print unzipped_data # all the junk in my commit! 

除了命令不打印头('commit',后跟内容的大小和一个空字节)之外,你将会看到和'git cat-file -p [hash]'的输出几乎相同。

我厌倦了没有一个好的解决scheme,所以我把一些东西在NPM:

https://github.com/jezell/zlibber

现在只需pipe道充气/放气命令。

git对象被zlib而不是gzip压缩,所以要么使用zlib解压缩,要么使用git命令,即git cat-file -p <SHA1>来打印内容。

看起来像马克·阿德勒有我们的想法,并写了一个例子,只是如何做到这一点: http : //www.zlib.net/zpipe.c

它仅仅编译了gcc -lz和安装的zlib头文件。 我在使用git的东西时将生成的二进制文件复制到我的/usr/local/bin/zpipe

 // save this as deflate.go package main import ( "compress/zlib" "io" "os" "flag" ) var infile = flag.String("f", "", "infile") func main() { flag.Parse() file, _ := os.Open(*infile) r, err := zlib.NewReader(file) if err != nil { panic(err) } io.Copy(os.Stdout, r) r.Close() } 

 $ go build deflate.go $ ./deflate -f .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 

请参阅http://en.wikipedia.org/wiki/DEFLATE#Encoder_implementations

它列出了一些软件实现,包括gzip,所以应该工作。 你有没有尝试只是在文件上运行gzip? 它不会自动识别格式吗?

你怎么知道它是用DEFLATE压缩的? 什么工具被用来压缩文件?

我发现这个问题寻找解决方法,在刚刚安装的hadoop dfs客户端的新版本中使用了-text实用工具。 除了正在读取的文件被压缩之外, -text工具像cat一样工作,它透明地解压缩并输出纯文本(因此名字)。

已经发布的答案肯定有帮助,但是其中一些在处理Hadoop大小的数据时遇到了一个问题 – 它们在解压之前将所有内容都读入内存。

所以,这里是我在上面的PerlPython答案的变化,没有这个限制:

python:

 hadoop fs -cat /path/to/example.deflate | python -c 'import zlib,sys;map(lambda b:sys.stdout.write(zlib.decompress(b)),iter(lambda:sys.stdin.read(4096),""))' 

Perl的:

 hadoop fs -cat /path/to/example.deflate | perl -MCompress::Zlib -e 'print uncompress($buf) while sysread(STDIN,$buf,4096)' 

请注意使用-cat子命令,而不是-text 。 这是为了让我的解决scheme在修复bug后不会中断。 道歉的python版本的可读性。

git对象是zlibstream(不是原始的deflate)。 pigz会用-dz选项解压缩。

你为什么不使用git的工具来访问数据? 这应该能够读取任何git对象:

 git show --pretty=raw <object SHA-1> 

pigz可以做到这一点:

 apt-get install pigz unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 
 const zlib = require("zlib"); const adler32 = require("adler32"); const data = "hello world~!"; const chksum = adler32.sum(new Buffer(data)).toString(16); console.log("789c",zlib.deflateRawSync(data).toString("hex"),chksum); // or console.log(zlib.deflateSync(data).toString("hex"));