Как распаковать файл в Ruby on Rails? - PullRequest
38 голосов
/ 09 февраля 2012

Я загружаю файл на сервер в Ruby on Rails

Обычно это текстовый файл, и я сохраняю его в модели как поле «файл» в ActiveRecord для отправки с другими полями, такими как заголовок представления и т. Д.

Однако пользователь также может отправить zip-файл. В этом случае zip-файл должен быть разархивирован, и для каждого файла в zip-файле должна быть создана новая заявка с теми же текстовыми полями, но с текущим файлом.

Как мне это сделать?

Я посмотрел примеры распаковки в сети, но большинство использует каталог для распаковки файлов. Я не уверен, что мне нужно, как в текущем методе создания SubmissionsController, объект файла получен, и я предполагаю, что путь для сохранения файла автоматически генерируется при вызове метода сохранения Submission. Поэтому я подумал, что, возможно, мне следует разархивировать zip-файл в памяти, чтобы получить массив файловых объектов, а затем создать новое представление с каждым файловым объектом, но с теми же полями, а затем позволить ActiveRecord сгенерировать пути к файлам для каждого, когда он сохранит их в база данных. Я могу ошибаться, потому что я новичок в Rails и Ruby.

Ответы [ 3 ]

41 голосов
/ 09 февраля 2012

Я бы использовал rubyzip gem .В частности, эта часть: https://github.com/rubyzip/rubyzip/blob/master/lib/zip/filesystem.rb

Создает в памяти искусственную файловую систему, отражающую содержимое zip-файла.Вот пример, основанный на примере из документов:

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

В вашем случае просто поместите имя загруженного временного файла, где my.zip в примереи вы можете просматривать содержимое и выполнять с ним регулярные операции.

25 голосов
/ 29 августа 2013

Со страницы проекта RubyZip:

Изменен интерфейс Rubyzip !!!Нет необходимости запрашивать zip / zip и префикс Zip в именах классов.

Итак, пример кода из @ ben-lee должен быть обновлен до следующего вида:

require 'zip'

Zip::File.open("my.zip") do |zipfile|
  zipfile.each do |file|
    # do something with file
  end
end
16 голосов
/ 12 мая 2016

Распаковка Zip-файлов в Ruby

После установки гема rubyzip вы можете использовать этот метод для извлечения 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

Вы используете это так:

extract_zip(zip_path, extract_destination)
...