2009-11-11 4 views
1

Je passe un emplacement de fichier zip dynamique à un def d'une base de données. Je veux décompresser le fichier à un emplacement temporaire, extraire le fichier de rapport xml à l'intérieur, appliquer une feuille de style xslt, le copier en tant que rhtml dans un répertoire de vue pour le rendu, et supprimer le fichier xml extrait de temp. La fonctionnalité fonctionne bien (le fichier rhtml est écrasé à chaque fois et restitue) sauf qu'il extrait du même zip parent pour chaque exécution et que le xml extrait ne peut pas être supprimé, ce qui me porte à croire que la première exécution ne ferme pas le parent zip (libérant sa poignée). Par conséquent, les exécutions suivantes extraient le fichier XML à partir du premier fichier zip exécuté. J'ai essayé "Zip :: ZipFile.close", "zipFichier = Zip :: ZipFile.open (fileLocation); zipFile.close", "File.close (fileLocation)", et d'autres permutations. Toute aide serait appréciée.Comment fermer un ZipFile

Répondre

0

Pouvez-vous passer un bloc à Zip :: ZipFile.open? Cela fermera lorsque les sorties de bloc:

Zip::ZipFile.open(file_name) do |zip_file| 
    zip_file.extract('report.xml', '/tmp') 
end 

# zip file is closed at this point 
# apply_xslt 
# copy rhtml to app/views/... 
# etc 

== EDIT ==

Sur la base de vos commentaires, voici un exemple de travail:

require 'rubygems' 
require 'zip/zip' 
require 'fileutils' 

zip_file_name = 'test.zip' 
out_dir = 'tmp_for_zip' 
FileUtils.mkdir_p out_dir 

Zip::ZipFile.open(zip_file_name) do |zip_file| 
    report_name = File.basename(zip_file.name).gsub('zip', 'xml') 
    out = File.join(out_dir, report_name) 
    zip_file.extract(report_name, out) unless File.exists?(out) 
    puts "extracted #{report_name} to #{out}" 
end 

En outre, je ne sais pas si vous utilisez unix, mais vous pouvez utiliser lsof (liste des fichiers ouverts) pour savoir si le fichier est réellement ouvert:

lsof | grep your_file_name 
+0

Je ne connais pas le nom o f le fichier 'report.xml'. Je l'ai fait dynamiquement avec une boucle: Zip :: ZipFile.open (fichier.to_s) {| zip_file | zip_file.each {| f | @Base = File.basename (f.name) @f_path = File.join (tempDir, base de @) \t \t \t FileUtils.mkdir_p (File.dirname (@f_path)) zip_file.extract (f, @f_path) à moins File.exist? (@ f_path) zip_file.close } \t \t \t } le nom de 'report.xml' a le même nom de racine que le zip ("blah_report.xml" est dans « blah_report. zip ") donc je suppose que je pourrais l'analyser mais cela semble être une douleur (et pas trop effecient - ou élégant) –

+0

Y at-il un moyen de faire" zip_file.extract (first, '/ tmp') "? Il n'y aura qu'un seul rapport par zip. –

+0

Malheureusement, votre code donne le même résultat que mon original. J'ai encore 2 problèmes. Une fois le xml extrait, je l'utilise pour créer un objet Document XML, appliquer une feuille de style XSLT et copier le résultat dans "views /.../ sampleReport.rhtml" pour le rendu. Le fichier XML d'origine ne peut pas être supprimé (par le biais du code ou à la main) tant que le serveur n'est pas éteint pour libérer le fichier. (Est-il possible que l'objet Doc s'y accroche, pas le parent zip). De plus, le rendu d'un nouveau rhtml montre toujours le résultat de la première exécution même si j'ai vérifié que le rhtml a changé. Serait-ce un problème de mise en cache? –