【问题标题】:How to decompress Gzip string in ruby?如何在 ruby​​ 中解压缩 Gzip 字符串?
【发布时间】:2010-11-24 14:47:37
【问题描述】:

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

我应该如何解压缩一个字符串?

【问题讨论】:

    标签: ruby gzip zlib


    【解决方案1】:

    上述方法对我不起作用。
    我不断收到incorrect header check (Zlib::DataError) 错误。显然,它假定您默认有一个标题,但情况可能并非总是如此。

    我实施的解决方法是:

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

    【讨论】:

    • 谢谢,我遇到了同样的错误,这解决了我的问题!
    • 调用 body.to_s 是多余的吗?
    【解决方案2】:

    Zlib 默认假定您的压缩数据包含一个标头。 如果您的数据不包含标头,它将通过引发 Zlib::DataError 失败。

    您可以通过以下解决方法告诉 Zlib 假设数据没有标头:

    def inflate(string)
      zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
      buf = zstream.inflate(string)
      zstream.finish
      zstream.close
      buf
    end
    

    【讨论】:

      【解决方案3】:

      您需要 Zlib::Inflate 来解压缩字符串,需要 Zlib::Deflate 来进行压缩

        def inflate(string)
          zstream = Zlib::Inflate.new
          buf = zstream.inflate(string)
          zstream.finish
          zstream.close
          buf
        end
      

      【讨论】:

        【解决方案4】:

        在 Rails 中你可以使用:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 不错的一个。从the docs "或添加 16 以仅解码 gzip 格式(非 gzip 流将引发 Zlib::DataError)"
          【解决方案6】:

          使用(-Zlib::MAX_WBITS),我得到了ERROR: invalid code lengths set 和ERROR: invalid block type
          唯一的以下对我也有用。

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

          【讨论】:

            【解决方案7】:

            我使用上面的答案来使用 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
            

            【讨论】:

              【解决方案8】:

              要压缩内容,请使用以下代码(在 1.9.2 上测试)

              Zlib::GzipReader.new(StringIO.new(content), :external_encoding => content.encoding).read
              

              注意编码问题

              【讨论】:

                【解决方案9】:

                这些天我们不需要任何额外的参数。有 deflate 和 inflate 类方法允许像这样的快速单行:

                >> 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!"
                

                我认为它回答了“我应该如何解压缩字符串?”的问题。最好的。 :)

                【讨论】:

                • 如果你压缩和解压缩那么这会很好,但它不会被gzip压缩。仅在 gzip 压缩数据上运行 Zlib::Inflate.inflate(compressed) 将假定错误压缩并抛出“不正确的标头检查”异常。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-04-07
                • 1970-01-01
                • 2012-01-20
                • 1970-01-01
                • 2011-08-18
                • 2015-02-06
                • 2013-12-15
                相关资源
                最近更新 更多