See 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
Question
I have a zip archive in a string, but the rubyzip gem appears to want input from a file. The best I've come up with is to write the zip archive to a tempfile for the sole purpose of passing the filename to Zip::ZipFile.foreach()
, but this seems tortured:
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
Is there a simpler way?
NOTE: See also Ruby Unzip String.
Solution
See 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
OTHER TIPS
@maerics's answer introduced me to the zipruby gem (not to be confused with the rubyzip gem). It works well. My complete code ended up like this:
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
Ruby's StringIO would help in this case.
Think of it as a string/buffer you can treat like an in-memory file.