7
votes

Utiliser RubyZip pour ajouter des fichiers et des annuaires imbriqués à un zipOutPutStream

Je me débats avec une rubiscipe pour ajouter des annuaires à un zipOutputStream. (Je veux le flux de sortie afin que je puisse l'envoyer à partir d'un contrôleur de rails). Mon code suit cet exemple:

http://info.michael-simons.eu/2008/01/21/USTION-RUBYZIP-O-CREATTE-ZIP-FILES-ON-TRE-FLES/

Lorsque modifié pour inclure des répertoires dans la liste des fichiers pour ajouter i Obtenir l'erreur suivante:

Toute aide serait grandement appréciée.

mise à jour

Après avoir essayé un certain nombre de solutions, j'ai eu le meilleur succès avec ZipRuby qui possède une API propre et de bons exemples: http: / /zipruby.rubyforge.org/ .


1 commentaires

Très bon travail trouvant ZipRuby, a sauvé ma journée!


4 Réponses :


3
votes

ooooouuuhh ... vous voulez vraiment zippy. C'est un plugin de rails qui résume beaucoup la complexité de RubyZip et vous permet de créer de quoi vous parlez, y compris des répertoires (de ce que je me souviens).

Vous allez: P>

http://github.com/Toretore/zippy p>

et directement à partir du site Zippy : p> xxx pré>

modifier strud>: modifiant par commentaire d'utilisateur: p>

hmm ... tout l'objectif d'utiliser Zippy est de faire Il est beaucoup plus facile d'utiliser Ruby Zip. Vous voudrez peut-être prendre une seconde (ou d'abord) regarder ... P>

Voici comment créer un répertoire avec des répertoires: P>

some_var = Zippy.open('awsum.zip') do |zip|
  %w{dir_a dir_b dir_c diri}.each do |dir|  
    zip["bin/#{dir}/"]
  end
end

...

send_file some_var, :file_name => ...


5 commentaires

Merci, cela a l'air bien mais les docs sont un peu timides et je n'ai pas le temps de plonger à travers la source tout à fait. Ainsi, par exemple, comment créerais-je un flux zip et ajouter un répertoire de répertoires? De plus, je dois utiliser SendFile plutôt qu'un type MIME personnalisé. Merci.


Correction de la réponse au cas où vous êtes intéressé.


Désolé, mais j'ai trouvé que cette gemme sera un travail assez acharné. Il y a quelques autres d'autres que je vais essayer que cela puisse diffuser un zip nouvellement créé de la manière dont je veux.


@belles, Zippy a l'air bien mais il n'y a vraiment pas de docs pour cela. Vous connaissez-vous des liens vers un exemple de code? Votre exemple de création de répertoires (vides) est un bon départ, mais ce que je veux faire est de copier récursivement un répertoire rempli de fichiers et de sous-répertoires existants. Je n'ai pas encore trouvé d'exemples de la manière de copier un seul fichier (seulement comment écrire de nouveaux).


Désolé, je ne connais aucun lien, mais vous pouvez trouver les spécifications au moins un peu utiles. : - /



9
votes
Zip::ZipFile.open(path, Zip::ZipFile::CREATE) do |zip|
  songs.each do |song|
    zip.add "record/#{song.title.parameterize}.mp3", song.file.to_file.path
  end
end

0 commentaires

3
votes

Zippy fonctionnera pour cela. Il peut y avoir une façon plus cool de le faire, mais car il n'y a essentiellement pas de docs, voici ce que je suis venu avec des répertoires de copie récursives avec Zippy dans un filefile. Ce rakeFile est utilisé dans un environnement de rails, donc je mets des exigences de gemme dans mon gemfile: xxx

et c'est le rakefile xxx

maintenant je peut l'utiliser comme ceci: xxx

et il produira mon.zip qui contient un répertoire interne appelé "My" avec des copies de fichiers sélectionnés et Répertoires.


0 commentaires

3
votes

J'ai pu obtenir des annuaires fonctionnant avec le même zipOutputStream code> utilisé dans le Article original .

Tout ce que je devais faire était d'ajouter le répertoire lors de l'appelant zos.put_next_enry code>. p>

Par exemple: p>

require 'zip/zip'
require 'zip/zipfilesystem'

t = Tempfile.new("some-weird-temp-file-basename-#{request.remote_ip}")
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
  some_file_list.each do |file|
    # Create a new entry with some arbitrary name
    zos.put_next_entry("myfolder/some-funny-name.jpg") # Added myfolder/
    # Add the contents of the file, don't read the stuff linewise if its binary, instead use direct IO
    zos.print IO.read(file.path)
  end
end
# End of the block  automatically closes the file.
# Send it using the right mime type, with a download window and some nice file name.
send_file t.path, :type => 'application/zip', :disposition => 'attachment', :filename => "some-brilliant-file-name.zip"
# The temp file will be deleted some time...
t.close


1 commentaires

Votre méthode a fonctionné bien, merci! J'ai presque changé de ZipRuby , mais cela ne semble plus être maintenu.