How to unzip a file in Ruby on Rails?
I'd use the rubyzip gem. Specifically this part: https://github.com/rubyzip/rubyzip/blob/master/lib/zip/filesystem.rb
It creates an artificial file system in memory mirroring the contents of the zip file. Here's an example based of the example from the docs:
Rubyzip interface changed!!! No need to do require "zip/zip" and Zip prefix in class names removed.
require 'zip'
Zip::File.open("my.zip") do |zipfile|
zipfile.each do |file|
# do something with file
end
end
In your case, just put the name of the uploaded tempfile where my.zip
is in the example, and you can loop through the contents and do your regular operations on them.
How to unzip a zip file containing folders and files in rails, while keeping the directory structure
This worked for me. Gave the same result as you would expect when unzipping a zipped folder with subfolders and files.
Zip::Zip.open(file_path) do |zip_file|
zip_file.each do |f|
f_path = File.join("destination_path", f.name)
FileUtils.mkdir_p(File.dirname(f_path))
zip_file.extract(f, f_path) unless File.exist?(f_path)
end
end
The solution from this site:
http://bytes.com/topic/ruby/answers/862663-unzipping-file-upload-ruby
How to unzip a file with ruby
The problem with installing the gem that way is that you're shelling out to another process with:
`gem install rubyzip`
and after that finishes installing the gem, your current irb
session still won't see it. You'd have to reload irb
with exec "irb"
and then calling require 'zip'
again.
Note: those are backticks not single quotes.
Try this:
begin
require 'zip'
rescue LoadError
`gem install rubyzip`
exec "irb"
retry
end
For me require 'zip'
works. I have rubyzip-1.1.2
Now you should be able to use Zip
Also, the gem
command is rubygems. So you can't install rubygems with itself. It should already be installed, but if not try this: http://rubygems.org/pages/download
Ruby: Download zip file and extract
I found the solution myself and then at stackoverflow :D (How to iterate through an in-memory zip file in Ruby)
input = HTTParty.get("http://example.com/somedata.zip").body
Zip::InputStream.open(StringIO.new(input)) do |io|
while entry = io.get_next_entry
puts entry.name
parse_zip_content io.read
end
end
- Download your ZIP file, I'm using HTTParty for this (but you could also use ruby's
open
command (require 'open-uri'
). - Convert it into a
StringIO
stream usingStringIO.new(input)
- Iterate over every entry inside the ZIP archive using
io.get_next_entry
(it returns an instance ofEntry
) - With
io.read
you get the content, and withentry.name
you get the filename.
Related Topics
How to Automate Chrome Request Blocking Using Selenium-Webdriver for Ruby
Set Attribute Dynamically of Ruby Object
Why Does Array.Slice Behave Differently for (Length, N)
Is There an Expect Equivalent Gem for Ruby
Prevent Rails Test from Deleting Seed Data
Installing Jekyll on Ubuntu 14.04
Is It Possible for Rspec to Expect Change in Two Tables
Sum the Value of Array in Hash
What's the Difference Between Gets.Chomp() VS. Stdin.Gets.Chomp()
How to Alter the Timezone of a Datetime in Ruby
How to Fix Rubygems Recent Deprecation Warning
How to Simulate Java-Like Annotations in Ruby
Ruby on Rails: How to Explicitly Define Plural Names and Singular Names in Rails
How to Require Active Record Working Outside of Rails
Problems with the Rails Console, Rvm and Readline
How to Decompress Gzip String in Ruby
Why Does Ruby Have Trueclass and Falseclass Instead of a Single Boolean Class