2013-02-15 4 views
1

У меня есть zip-архив в строке, но, похоже, gim rubyzip хочет ввода из файла. Лучшее, что я придумал, чтобы написать архив зип к TempFile с единственной целью передачи имени файла в Zip::ZipFile.foreach(), но это, кажется, пыткам:разархивировать zip-архив из строки

require 'zip/zip' 
def unzip(page) 
    "".tap do |str| 
    Tempfile.open("unzip") do |tmpfile| 
     tmpfile.write(page) 
     Zip::ZipFile.foreach(tmpfile.path()) do |zip_entry| 
     zip_entry.get_input_stream {|io| str << io.read} 
     end 
    end 
    end 
end 

Есть более простой способ?

ПРИМЕЧАНИЕ: См. Также Ruby Unzip String.

ответ

3

См Zip/Ruby Zip::Archive.open_buffer(...):

require 'zipruby' 
Zip::Archive.open_buffer(str) do |archive| 
    archive.each do |entry| 
    entry.name 
    entry.read 
    end 
end 
+0

Спасибо, что хорошо работает! См. Мой полный ответ в http://stackoverflow.com/a/14912237/558639 –

-1

Руби StringIO бы помочь в этом случае.

Думайте об этом как о строке/буфере, которую вы можете рассматривать как файл в памяти.

+0

Я знаю все о StringIO. Я не думаю, что Zip :: ZipFile может обрабатывать объект StringIO, хотя я был бы счастлив оказаться ошибочным. –

+0

требуется имя файла. не потоковый объект – sergeych

0

@ Ответ maerics представил мне zipruby gem (не путать с камнем rubyzip). Это работает хорошо. Мой полный код закончился следующим образом:

require 'zipruby' 

# Given a string in zip format, return a hash where 
# each key is an zip archive entry name and each 
# value is the un-zipped contents of the entry 
def unzip(zipfile) 
    {}.tap do |entries| 
    Zip::Archive.open_buffer(zipfile) do |archive| 
     archive.each do |entry| 
     entries[entry.name] = entry.read 
     end 
    end 
    end 
end