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?
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
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
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
zstream = Zlib :: Inflate.new (16 + Zlib :: MAX_WBITS)
Dans Rails vous pouvez utiliser:
ActiveSupport::Gzip.compress("my string")
ActiveSupport::Gzip.decompress()
.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
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. :)
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
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