在Ruby中使用Zlib解压缩.gz文件

7

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

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 文件。有人知道我该如何正确地做吗?
2个回答

26

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

在幕后,这将尝试在Linux上某些特定情况下可用的sendfile系统调用。否则,它会以16KB块快速使用C代码进行复制。这是我从Ruby 1.9.1源代码中学到的。


3
这里是一个Ruby单行代码(先cd .git/并确定任何对象的路径):
ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接