2013-02-15 45 views
1

我在一個字符串中有一個zip歸檔文件,但rubyzip gem似乎想要從一個文件輸入。我拿出最好的是寫的zip壓縮包來傳遞文件名以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 – 2013-02-16 16:04:36

-1

Ruby的StringIO會在這種情況下幫助。

把它看作一個字符串/緩衝區,你可以像內存文件一樣對待。

+0

查看我完整的答案我知道所有關於StringIO的信息。我不認爲Zip :: ZipFile可以處理一個StringIO對象,但我很樂意被證明是錯誤的。 – 2013-02-16 06:17:49

+0

它需要文件名。不是流式物體 – sergeych 2016-02-18 16:51:15

0

@ maerics的回答向我介紹了zipruby gem(不要與rubyzip gem混淆)。它運作良好。我的完整代碼如下所示:

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