如何在Ruby中解压Gzip字符串?

57

Zlib::GzipReader可以接收“一个IO对象或类似IO的对象”作为其输入,正如文档中所述。

Zlib::GzipReader.open('hoge.gz') {|gz|
  print gz.read
}

File.open('hoge.gz') do |f|
  gz = Zlib::GzipReader.new(f)
  print gz.read
  gz.close
end

我该如何解压缩字符串?

9个回答

130

以上方法对我没用。
我一直收到incorrect header check (Zlib::DataError) 错误。 显然它默认假定您有一个头,但这并不总是正确的。

我的解决办法是:

require 'zlib'
require 'stringio'
gz = Zlib::GzipReader.new(StringIO.new(resp.body.to_s))    
uncompressed_string = gz.read

3
谢谢,我之前遇到了相同的错误,这个解决方案解决了我的问题! - Matt Huggins
调用 body.to_s 是多余的吗? - Blaskovicz

19
Zlib默认假定你的压缩数据包含一个头。 如果你的数据不包含头,它将通过引发Zlib :: DataError失败。
您可以通过以下解决方法告诉Zlib假定数据没有标题:
def inflate(string)
  zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
  buf = zstream.inflate(string)
  zstream.finish
  zstream.close
  buf
end

16

在Rails中,您可以使用以下代码:

  • ActiveSupport::Gzip.compress("my string")
  • ActiveSupport::Gzip.decompress()

16
你需要使用Zlib::Inflate来解压字符串,使用Zlib::Deflate来压缩。
  def inflate(string)
    zstream = Zlib::Inflate.new
    buf = zstream.inflate(string)
    zstream.finish
    zstream.close
    buf
  end

7

zstream = Zlib::Inflate.new(16+Zlib::MAX_WBITS)


2
不错。从文档中可以看到,“或者添加16来仅解码gzip格式(对于非gzip流将引发Zlib :: DataError)”。 - ian

5

使用(-Zlib::MAX_WBITS),我得到了ERROR: invalid code lengths setERROR: invalid block type的错误提示。
只有下面这个方法对我起作用。

Zlib::GzipReader.new(StringIO.new(response_body)).read

3
要解压缩内容,请使用以下代码(在1.9.2上进行了测试)
Zlib::GzipReader.new(StringIO.new(content), :external_encoding => content.encoding).read

注意编码问题


3

我使用上面的答案来使用Zlib::Deflate。

我一直得到损坏的文件(对于小文件),花费了很多时间才发现可以使用以下方法解决问题:

buf = zstream.deflate(string,Zlib::FINISH)

没有zstream.finish这行代码!

def self.deflate(string)
    zstream = Zlib::Deflate.new
    buf = zstream.deflate(string,Zlib::FINISH)
    zstream.close
    buf
end

3

现在我们不需要任何额外的参数。有deflateinflate类方法,可以使用简短的一行代码:

>> data = "Hello, Zlib!"
>> compressed = Zlib::Deflate.deflate(data)
=> "x\234\363H\315\311\311\327Q\210\312\311LR\004\000\032\305\003\363"
>> uncompressed = Zlib::Inflate.inflate(compressed)
=> "Hello, Zlib!"

我认为这是最好的回答“如何解压字符串?” :)

4
如果您进行压缩和解压操作,那么这样做是没问题的,但不会进行gzip压缩。如果对gzip压缩数据运行Zlib :: Inflate.inflate(compressed),将会假设错误的压缩方式,并抛出“incorrect header check”异常。 - philwhln

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