2009-11-11 245 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