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]'的输出几乎相同。
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大小的数据时遇到了一个问题 – 它们在解压之前将所有内容都读入内存。
所以,这里是我在上面的Perl
和Python
答案的变化,没有这个限制:
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"));