2012-02-09 3 views
31

Я загрузка файла на сервер в Ruby On RailsКак распаковать файл в Ruby on Rails?

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

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

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

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

ответ

33

Я бы использовал 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 

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

+0

Я вижу, так как я могу получить массив объектов файлов из архива? – siamii

+0

@ bizso09, я только что обновил, чтобы показать, как перебирать содержимое. Существует также простой учебник, объясняющий его здесь: http://www.markhneedham.com/blog/2008/10/02/ruby-unzipping-a-file-using-rubyzip/ –

+0

спасибо. Я попробую сейчас – siamii

25

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

интерфейс Rubyzip изменился !!! Не нужно требовать «zip/zip» и префикс Zip в именах классов.

Итак, пример кода из @ бен-подветренной должны быть обновлены, чтобы что-то вроде этого:

require 'zip' 

Zip::File.open("my.zip") do |zipfile| 
    zipfile.each do |file| 
    # do something with file 
    end 
end 
10

Извлечение Zip файлов в Рубине

После того, как вы установили на rubyzip драгоценный камень, вы этот метод можно использовать для извлечения архивных файлов:

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) 
+0

Я не знаю, было ли это изменено недавно или нет, но метод 'extract' принимает только один аргумент, и будет выдавать ошибку, если вы дадите ей два. – 0112

+0

В чем причина условия 'except File.exist? (Fpath)'? Это просто повторение поведения других инструментов? –