Ruby中的Zlib解压缩.gz [英] Zlib in Ruby to uncompress .gz
问题描述
我有一个包含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文档。有人知道我可以如何正确地做到这一点吗?
Zlib :: GzipReader 像Ruby中的大多数 IO
类的类一样工作。你有一个打开
调用,并且当你传递一个块给它时,块会收到 IO
类对象。想想这是在块的持续时间内用文件或资源做一些事情的便捷方式。 但是这意味着在你的例子 gz 是一个
IO
类似的对象,而不是你所期望的gzip文件的内容。你仍然需要阅读
来达到目的。最简单的修复方法是:
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
syscall。否则,它将一次执行快速C代码16KB块的复制。这是我从Ruby 1.9.1源代码中学到的。I have a .gz file that contains an XML document. Does anyone know how to use Zlib properly? So far, I have the following code:
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() }
But this creates a blank .xml document. Does anyone know how I can properly do this?
解决方案
Zlib::GzipReader
works like mostIO
-like classes do in Ruby. You have anopen
call, and when you pass a block to it, the block will receive theIO
-like object. Think of it is convenient way of doing something with a file or resource for the duration of the block.But that means that in your example
gz
is anIO
-like object, and not actually the contents of the gzip file, as you expect. You still need toread
from it to get to that. The simplest fix would then be:g.write(gz.read)
Note that this will read the entire contents of the uncompressed gzip into memory.
If all you're really doing is copying from one file to another, you can use the more efficient
IO.copy_stream
method. Your example might then look like: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
Behind the scenes, this will try to use the
sendfile
syscall available in some specific situations on Linux. Otherwise, it will do the copying in fast C code 16KB blocks at a time. This I learned from the Ruby 1.9.1 source code.这篇关于Ruby中的Zlib解压缩.gz的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!