2009-11-11 243 views
1

我将一个动态zip文件位置从数据库传递给def。我想将文件解压缩到一个临时位置,在里面提取xml报告文件,应用一个xslt样式表,将它作为一个rhtml复制到一个视图目录进行渲染,然后删除temp提取的xml文件。该功能工作正常(rhtml文件每次都被覆盖并呈现),除非它从每个执行的同一父zip中提取,并且提取的xml不能被删除,这导致我相信第一次执行不会关闭父项拉链(释放其手柄)。因此,后续执行是从执行的第一个zip中提取xml。我试过“Zip :: ZipFile.close”,“zipFile = Zip :: ZipFile.open(fileLocation); zipFile.close”,“File.close(fileLocation)”和其他排列组合。 任何帮助,将不胜感激。如何关闭ZipFile

回答

0

你可以传递一个块到Zip :: ZipFile.open吗?这将关闭它,当块退出:

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 

== ==编辑

根据您的意见,这里有一个工作示例:

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 

另外,我不知道您正在运行一个unix,但是您可以使用lsof(列出打开的文件)来确定文件是否实际打开:

lsof | grep your_file_name 
+0

我不知道名称o f'report.xml'。我一直在动态地使用循环: Zip :: ZipFile.open(file.to_s){| zip_file | zip_file.each {| f | @base = File.basename(f.name) @f_path = File.join(的tempDir,@基)\t \t \t FileUtils.mkdir_p(File.dirname(@f_path)) zip_file.extract(F,@f_path ),除非File.exist?(@ f_path) zip_file.close } \t \t \t } 的 'report.xml将' 的名称具有相同的根名称作为拉链( “blah_report.xml” 是“blah_report。 zip“),所以我想我可以解析它,但这看起来像一个痛苦(而不是太有效 - 或优雅) – 2009-11-11 21:22:19

+0

有没有办法”zip_file.extract(第一,'/ tmp')“?每个邮编只会有1个报告。 – 2009-11-11 21:23:07

+0

不幸的是你的代码产生的结果与我的原始结果相同。我仍然有2个问题。一旦XML被提取,我用它来创建一个XML文档对象,应用一个XSLT样式表,并将结果复制到“views /.../ sampleReport.rhtml”来渲染。直到服务器关闭以释放文件时,才能删除原始xml(通过代码或手动)。 (是否有可能Doc对象仍然坚持它,而不是拉链父母)。此外,即使我已验证rhtml已更改,但呈现新的rhtml始终会显示第一次执行的结果。这可能是缓存问题吗? – 2009-11-12 03:23:03