web-dev-qa-db-fra.com

Comment décompresser la chaîne Gzip en rubis?

Zlib :: GzipReader peut prendre "un objet IO ou IO-like". comme c'est entrée, comme indiqué dans les documents.

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 décompresser une chaîne?

47
Fluffy

La méthode ci-dessus n'a pas fonctionné pour moi.
J'obtenais toujours une erreur incorrect header check (Zlib::DataError). Apparemment, cela suppose que vous avez un en-tête par défaut, ce qui n'est pas toujours le cas.

Le travail autour que j'ai mis en œuvre était:

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

Zlib suppose par défaut 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 lançant un Zlib :: DataError.

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

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

Vous avez besoin de Zlib :: Inflate 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
dimus

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

7
BearPy

Dans Rails vous pouvez utiliser:

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

En utilisant (-Zlib::MAX_WBITS), J'ai eu ERROR: invalid code lengths set et ERROR: invalid block type
La seule chose suivante fonctionne aussi pour moi.

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

De nos jours, nous n'avons pas besoin de paramètres supplémentaires. Il existe des méthodes de classe deflate et inflate qui permettent des oneliners rapides comme ceux-ci:

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

Je pense que cela répond à la question "Comment dois-je décompresser une chaîne?" le meilleur. :)

3
Alex Fortuna

Pour 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

3
pinguin666

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 plusieurs heures pour comprendre que le problème peut être résolu en utilisant:

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

sans la ligne zstream.finish!

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