I know how to retrieve the contents of a normal zip-file with rubyzip. But i got trouble unzipping the contents of a zipped folder and i hope any of u guys can help me out.
this is the code i use to unzip:
Zip::ZipFile::open(@file_location) do |zip|
zip.each do |entry|
next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
logger.debug "#{entry.name}"
@data = File.new("#{Rails.root.to_s}/tmp/#{entry.name}")
end
end
entry.name gives me the name of the file inside the zip-file. This works perfectly with a normal zipfile. But when the zipfile is created from a folder, then the name of the entries are something like: test-folder/test.pdf. When i then try to create the file, it tells me the file can not be found. This is probably because it is inside the "test"-folder that is inside the zip.
If i check the entry to be a folder, no folder can be found. So i thought the solution to be to read the entry as a stream and then save it as a file. It is easy to get the entry-stream, but how do I save it as a file? This is what i got so far.
Zip::ZipFile::open(@file_location) do |zip|
zip.each do |entry|
next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
logger.debug "#{entry.name}"
@data = entry.get_input_stream.read
# How do i create a file from a stream?
end
end
Basically my question is: how can i create a file from a stream? Or is there an easier approach to this than mine?
===EDIT=== I use paperclip to store the files.
I found that a simpler approach based on jhwist's worked ok:
Zip::File.open(@file_location) do |zipfile|
zipfile.each do |entry|
# The 'next if...' code can go here, though I didn't use it
unless File.exist?(entry.name)
FileUtils::mkdir_p(File.dirname(entry.name))
zipfile.extract(entry, entry.name)
end
end
end
The conditional is obviously optional, but without it the code will raise an error if it tries to overwrite an existing file.