2010-07-02 134 views
7

我有一个包含XML文档的.gz文件。有谁知道如何正确使用Zlib?到目前为止,我有以下代码:Ruby中的Zlib解压缩.gz

require 'zlib' 
Zlib::GzipReader.open('PRIDE_Exp_Complete_Ac_1015.xml.gz') { |gz| 
    g = File.new("PRIDE_Exp_Complete_Ac_1015.xml", "w") 
     g.write(gz) 
     g.close() 
} 

但是,这会创建一个空白的.xml文档。有谁知道我可以如何正确地做到这一点?

回答

22

Zlib::GzipReader像大多数类似于Ruby的IO类。你有一个open调用,当你传递一个块时,块将会收到类似于IO的对象。想想这是在块的持续时间内使用文件或资源进行某些操作的便捷方式。

但这意味着在您的示例中,gz是一个类似于IO的对象,并且实际上并不像您期望的那样是gzip文件的内容。你仍然需要read来达到目的。然后,简单的解决办法是:

g.write(gz.read) 

注意,这将读取未压缩的gzip的全部内容到内存中。

如果您真的在做的是从一个文件复制到另一个文件,您可以使用更高效的方法IO.copy_stream。然后,您的例子可能是这样的:

Zlib::GzipReader.open('PRIDE_Exp_Complete_Ac_1015.xml.gz') do | input_stream | 
    File.open("PRIDE_Exp_Complete_Ac_1015.xml", "w") do |output_stream| 
    IO.copy_stream(input_stream, output_stream) 
    end 
end 

在幕后,这将尝试使用可用的系统调用sendfile在Linux上的一些具体情况。否则,它将一次执行快速C代码16KB块的复制。这是我从Ruby 1.9.1源代码中学到的。

2

这里是一个红宝石单行(CD的.git /第一和识别路径的任何对象):

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