如何在 Ruby on Rails 中解压缩文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9204423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to unzip a file in Ruby on Rails?
提问by siamii
I'm uploading a file to the server in Ruby on Rails
我正在使用 Ruby on Rails 将文件上传到服务器
Normally, it's a text file and I save it in the model as a 'file' field in a Submission ActiveRecord with other fields such as title of submission.. etc.
通常,它是一个文本文件,我将它保存在模型中作为提交 ActiveRecord 中的“文件”字段以及其他字段,例如提交标题等。
However, the user can also submit a zip file. In this case the zipfile should unzipped and for each file in the zip a new Submission should be created with the same text fields, but current file.
但是,用户也可以提交 zip 文件。在这种情况下,zipfile 应该解压缩,并且对于 zip 中的每个文件,应该使用相同的文本字段创建一个新的提交,但是是当前文件。
How can I accomplish this?
我怎样才能做到这一点?
I looked at unzip examples on the net, but most use a directory to unzip the files to. I'm not sure if I need that as in the current create method of SubmissionsController, a file object is received and I presume the path to save the file to is automatically generated when the Submission save method is called. So I was thinking that maybe I should unzip the zipfile in memory to get an array of file objects and then create a new Submission with each file object but same fields and then let ActiveRecord generate the file paths for each one when it saves them to the database. I might be wrong here, because I'm kind of new to Rails and Ruby.
我在网上查看了解压缩示例,但大多数使用目录将文件解压缩到。我不确定是否需要像当前 SubmissionsController 的 create 方法一样,接收到一个文件对象,并且我假设在调用 Submission save 方法时自动生成保存文件的路径。所以我在想,也许我应该在内存中解压缩 zipfile 以获得一组文件对象,然后使用每个文件对象但相同的字段创建一个新的提交,然后让 ActiveRecord 在将它们保存到每个文件时为每个文件生成文件路径数据库。我在这里可能是错的,因为我是 Rails 和 Ruby 的新手。
回答by Ben Lee
I'd use the rubyzip gem. Specifically this part: https://github.com/rubyzip/rubyzip/blob/master/lib/zip/filesystem.rb
我会使用rubyzip gem。具体这部分: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:
它在内存中创建一个人工文件系统,镜像 zip 文件的内容。这是基于文档示例的示例:
Rubyzip interface changed!!! No need to do require "zip/zip" and Zip prefix in class names removed.
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.zipis in the example, and you can loop through the contents and do your regular operations on them.
在您的情况下,只需将上传的临时文件的名称放在my.zip示例中的位置,您就可以遍历内容并对它们进行常规操作。
回答by Bill Ingram
From the RubyZip project page:
从 Ruby Zip 项目页面:
Rubyzip interface changed!!! No need to do require "zip/zip" and Zip prefix in class names removed.
Rubyzip 界面改变了!!!不需要删除类名中的“zip/zip”和 Zip 前缀。
So, the example code from @ben-lee should be updated to something like this:
因此,@ben-lee 的示例代码应更新为如下所示:
require 'zip'
Zip::File.open("my.zip") do |zipfile|
zipfile.each do |file|
# do something with file
end
end
回答by Sheharyar
Extract Zip files in Ruby
在 Ruby 中提取 Zip 文件
Once you've installed the rubyzipgem, you can use this method to extract zip files:
安装rubyzipgem 后,您可以使用此方法提取 zip 文件:
require 'zip'
def extract_zip(file, destination)
FileUtils.mkdir_p(destination)
Zip::File.open(file) do |zip_file|
zip_file.each do |f|
fpath = File.join(destination, f.name)
zip_file.extract(f, fpath) unless File.exist?(fpath)
end
end
end
You use it like this:
你像这样使用它:
extract_zip(zip_path, extract_destination)
回答by installero
Worked for me:
对我来说有效:
gem install rubyzip
main.rb
main.rb
require 'zip'
def extract_zip(file, destination)
FileUtils.mkdir_p(destination)
Zip::File.open(file) do |zip_file|
zip_file.each do |f|
fpath = File.join(destination, f.name)
FileUtils.mkdir_p(File.dirname(fpath))
zip_file.extract(f, fpath) unless File.exist?(fpath)
end
end
end
extract_zip('file.zip', 'tmp')

