web-dev-qa-db-fra.com

Comment décompresser un fichier en Ruby on Rails?

Je télécharge un fichier sur le serveur en Ruby on Rails

Normalement, c'est un fichier texte et je l'enregistre dans le modèle en tant que champ "fichier" dans un enregistrement actif de soumission avec d'autres champs tels que le titre de la soumission .. etc.

Cependant, l'utilisateur peut également soumettre un fichier Zip. Dans ce cas, le fichier zip doit être décompressé et pour chaque fichier dans le fichier Zip, une nouvelle soumission doit être créée avec les mêmes champs de texte, mais le fichier actuel.

Comment puis-je accomplir cela?

J'ai regardé des exemples de décompression sur le net, mais la plupart utilisent un répertoire pour décompresser les fichiers. Je ne sais pas si j'en ai besoin, car dans la méthode de création actuelle de SubmissionsController, un objet fichier est reçu et je suppose que le chemin pour enregistrer le fichier est automatiquement généré lorsque la méthode d'enregistrement de soumission est appelée. Je pensais donc que je devrais peut-être décompresser le fichier zip en mémoire pour obtenir un tableau d'objets de fichier, puis créer une nouvelle soumission avec chaque objet de fichier, mais les mêmes champs, puis laisser ActiveRecord générer les chemins de fichier pour chacun lorsqu'il les enregistre dans le base de données. Je peux me tromper ici, parce que je suis un peu nouveau pour Rails et Ruby.

38
siamii

J'utiliserais le rubyzip gem . Plus précisément cette partie: https://github.com/rubyzip/rubyzip/blob/master/lib/Zip/filesystem.rb

Il crée un système de fichiers artificiel en mémoire reflétant le contenu du fichier Zip. Voici un exemple basé sur l'exemple des documents:

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

Dans votre cas, mettez simplement le nom du fichier temporaire téléchargé où my.Zip est dans l'exemple, et vous pouvez parcourir le contenu et effectuer vos opérations régulières sur celui-ci.

41
Ben Lee

Depuis la page du projet RubyZip:

L'interface Rubyzip a changé !!! Il n'est pas nécessaire de supprimer "Zip/zip" et le préfixe Zip dans les noms de classe.

Ainsi, l'exemple de code de @ ben-lee devrait être mis à jour avec quelque chose comme ceci:

require 'Zip'

Zip::File.open("my.Zip") do |zipfile|
  zipfile.each do |file|
    # do something with file
  end
end
25
Bill Ingram

Extraire des fichiers Zip dans Ruby

Une fois que vous avez installé la gemme rubyzip , vous pouvez utiliser cette méthode pour extraire des fichiers 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

Vous l'utilisez comme ceci:

extract_Zip(zip_path, extract_destination)
16
Sheharyar