Comment décompresser la chaîne Gzip dans ruby?

Zlib::GzipReader peut prendre "un IO, ou IO-objet similaire."d'entrée, comme indiqué dans les docs.

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

Comment dois-je décompresser une chaîne?

43
demandé sur Kris 2009-09-01 15:18:22

9 réponses

la méthode ci-dessus n'a pas fonctionné pour moi.

J'ai continué à obtenir incorrect header check (Zlib::DataError) erreur. Apparemment, il suppose que vous avez un en-tête par défaut, ce qui n'est pas toujours le cas.

le travail que j'ai mis en place était:

require 'zlib'
require 'stringio'
gz = Zlib::GzipReader.new(StringIO.new(resp.body.to_s))    
uncompressed_string = gz.read
110
répondu Garth 2015-03-30 16:34:15

Zlib par défaut suppose que vos données compressées contiennent un en-tête. Si vos données ne contiennent pas d'en-tête, elles échoueront en soulevant un Zlib::DataError.

Vous pouvez dire à Zlib de supposer que les données n'ont pas d'en-tête via la solution suivante:

def inflate(string)
  zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
  buf = zstream.inflate(string)
  zstream.finish
  zstream.close
  buf
end
18
répondu 2009-11-15 19:03:50

Vous avez besoin d' Zlib::Gonfler pour la décompression d'une chaîne et Zlib::Deflate pour la compression

  def inflate(string)
    zstream = Zlib::Inflate.new
    buf = zstream.inflate(string)
    zstream.finish
    zstream.close
    buf
  end
15
répondu dimus 2009-09-01 11:36:20

zstream = Zlib::gonfler.nouveau (16+Zlib::MAX_WBITS)

6
répondu BearPy 2014-01-16 05:09:48

en utilisant (-Zlib::MAX_WBITS), j'ai ERROR: invalid code lengths set et ERROR: invalid block type

La seule suite qui fonctionne pour moi, trop.

Zlib::GzipReader.new(StringIO.new(response_body)).read
5
répondu john 2011-09-25 01:05:32

dans les Rails vous pouvez utiliser:

  • ActiveSupport::Gzip.compress("my string")
  • ActiveSupport::Gzip.decompress().
5
répondu Tyler 2015-11-12 21:10:00

nous n'avons pas besoin de paramètres supplémentaires de nos jours. Il y a deflate et inflate classe de méthodes qui permettent rapide oneliners comme celles-ci:

>> data = "Hello, Zlib!"
>> compressed = Zlib::Deflate.deflate(data)
=> "x43H5117Q021LR402533"
>> uncompressed = Zlib::Inflate.inflate(compressed)
=> "Hello, Zlib!"

je pense qu'il répond à la question "Comment dois-je ungzip une chaîne de caractères?" Best. :)

3
répondu Alex Fortuna 2012-09-18 09:59:43

j'ai utilisé la réponse ci-dessus pour utiliser un Zlib::Deflate

j'ai continué à obtenir des fichiers cassés (pour les petits fichiers) et il a fallu de nombreuses heures pour comprendre que le problème peut être corrigé en utilisant:

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

sans le zstream.ligne d'arrivée!

def self.deflate(string)
    zstream = Zlib::Deflate.new
    buf = zstream.deflate(string,Zlib::FINISH)
    zstream.close
    buf
end
2
répondu Abdo 2011-03-30 20:15:44

gunzip contenu, utilisez le code suivant (testé sur 1.9.2)

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

attention aux problèmes d'encodage

2
répondu pinguin666 2011-10-18 09:28:08