2012-02-09 21 views
31

estoy cargue un archivo en el servidor en Ruby on Rails¿Cómo descomprimir un archivo en Ruby on Rails?

Normalmente, se trata de un archivo de texto y guardarlo en el modelo como un campo 'archivo' en un Envío ActiveRecord con otros campos como el título de la presentación .. etc.

Sin embargo, el usuario también puede enviar un archivo zip. En este caso, el archivo zip debe descomprimirse y para cada archivo en el archivo comprimido se debe crear una nueva Presentación con los mismos campos de texto, pero el archivo actual.

¿Cómo puedo lograr esto?

He visto ejemplos de descomprimir en la red, pero la mayoría usa un directorio para descomprimir los archivos. No estoy seguro si lo necesito como en el método de creación actual de SubmissionsController, se recibe un objeto de archivo y supongo que la ruta para guardar el archivo se genera automáticamente cuando se llama al método de envío de envío. Así que pensé que tal vez debería descomprimir el archivo zip en memoria para obtener una matriz de objetos de archivo y luego crear una nueva Presentación con cada objeto de archivo pero los mismos campos y luego dejar que ActiveRecord genere las rutas de archivos para cada uno cuando los guarda en el archivo base de datos. Podría estar equivocado aquí, porque soy nuevo en Rails y Ruby.

Respuesta

33

Yo usaría el rubyzip gem. Específicamente esta parte: https://github.com/rubyzip/rubyzip/blob/master/lib/zip/filesystem.rb

Crea un sistema de archivos artificial en la memoria que duplica el contenido del archivo zip. Aquí está un ejemplo basado en el ejemplo de la documentación:

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 

En su caso, sólo hay que poner el nombre del archivo temporal subido en my.zip es en el ejemplo, y puede recorrer el contenido y haz tus operaciones regulares en ellos.

+0

veo, así que ¿cómo podría conseguir una gran variedad de objetos de archivo del archivo zip? – siamii

+0

@ bizso09, Acabo de actualizar para mostrar cómo recorrer los contenidos. También hay un sencillo tutorial que lo explica aquí: http://www.markhneedham.com/blog/2008/10/02/ruby-unzipping-a-file-using-rubyzip/ –

+0

gracias. Lo intento ahora – siamii

25

Desde la página del proyecto RubyZip:

interfaz Rubyzip cambiado !!! No es necesario que requiera "zip/zip" y el prefijo Zip en los nombres de clase eliminados.

Por lo tanto, el código de ejemplo de @ debe actualizarse para algo como esto ben-lee:

require 'zip' 

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

extraer archivos Zip en Ruby

Una vez que haya instalado el rubyzip gema, que puede utilizar este método para extraer archivos 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 

Se utiliza la siguiente manera:

extract_zip(zip_path, extract_destination) 
+0

No sé si ha sido cambiado recientemente o no, pero el método 'extract' solo toma un arg, y lanzará un error si le das dos. – 0112

+0

¿Cuál es la razón detrás de la condición 'a menos que File.exist? (Fpath)'? ¿Es solo para reproducir el comportamiento de otras herramientas? –