2009-06-08 9 views
7

का उपयोग कर मौजूदा फ़ाइलों को ओवरराइट करने के लिए मैं कई फ़ाइलों के साथ फ़ाइल को अनजिप करने का प्रयास कर रहा हूं जो लक्ष्य निर्देशिका में पहले से मौजूद हो सकता है या नहीं। ऐसा लगता है कि फ़ाइल पहले से मौजूद है तो अपवाद फेंकना डिफ़ॉल्ट व्यवहार है।Rubyzip lib

मैं निर्देशिका में अनजिप कैसे हो सकता हूं और बस मौजूदा फ़ाइलों को ओवरराइट कर सकता हूं?

begin 
    Zip::ZipFile.open(source) do |zipfile| 
    dir = zipfile.dir 
    dir.entries('.').each do |entry| 
     zipfile.extract(entry, "#{target}/#{entry}") 
    end 
    end 
rescue Exception => e 
    log_error("Error unzipping file: #{local_zip} #{e.to_s}") 
end 

उत्तर

12

ऐसा लगता है कि निकालने() एक वैकल्पिक ब्लॉक (onExistsProc) है कि तुम क्या यह निर्धारित करने के लिए फ़ाइल के साथ क्या करना है अगर यह पहले से मौजूद है की अनुमति देता है लेता है - सच लौट अधिलेखित करने के लिए अपवाद बढ़ाने के लिए झूठा।

आप बस सभी मौजूदा फ़ाइलों को अधिलेखित करना चाहते हैं तो आपके कर सकता है:

zipfile.extract(entry, "#{target}/#{entry}") { true } 

आप कुछ और अधिक जटिल तर्क अलग ढंग से विशिष्ट प्रविष्टियों को संभालने के लिए क्या करना चाहते हैं, तो आप कर सकते हैं:

zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) } 

संपादित करें: निश्चित उत्तर - जैसा कि इंगमार हैमर द्वारा इंगित किया गया है, मेरे मूल उत्तर ने उपरोक्त वाक्यविन्यास का उपयोग करते समय ब्लॉक को पैरामीटर के रूप में पारित किया है।

+0

यह उत्तर वास्तव में पोस्ट के रूप में काम नहीं करता है। इंगमार हमर द्वारा पोस्ट किए गए उत्तर को देखें और उसे उनके सुधार के लिए एक बिंदु दें। –

1

संपादित करें:: संशोधित अगर यह पहले से मौजूद है लक्ष्य फ़ाइल को निकालने के लिए कोड

यहाँ मेरी कोड है।

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

def unzip_file(file, destination) 
    Zip::ZipFile.open(file) { |zip_file| 
    zip_file.each { |f| 
    f_path=File.join(destination, f.name) 
    if File.exist?(f_path) then 
     FileUtils.rm_rf f_path 
    end 
    FileUtils.mkdir_p(File.dirname(f_path)) 
    zip_file.extract(f, f_path) 
    } 
    } 
end 

unzip_file('/path/to/file.zip', '/unzip/target/dir') 

संपादित करें: यदि यह पहले से मौजूद है तो लक्ष्य निर्देशिका को हटाने के लिए संशोधित कोड।

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

def unzip_file(file, destination) 
    if File.exist?(destination) then 
    FileUtils.rm_rf destination 
    end 
    Zip::ZipFile.open(file) { |zip_file| 
    zip_file.each { |f| 
    f_path=File.join(destination, f.name) 
    FileUtils.mkdir_p(File.dirname(f_path)) 
    zip_file.extract(f, f_path) 
    } 
    } 
end 

unzip_file('/path/to/file.zip', '/unzip/target/dir') 

यहाँ the original code from Mark Needham है:

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

def unzip_file(file, destination) 
    Zip::ZipFile.open(file) { |zip_file| 
    zip_file.each { |f| 
    f_path=File.join(destination, f.name) 
    FileUtils.mkdir_p(File.dirname(f_path)) 
    zip_file.extract(f, f_path) unless File.exist?(f_path) 
    } 
    } 
end 

unzip_file('/path/to/file.zip', '/unzip/target/dir') 
+0

उत्तर के लिए धन्यवाद लेकिन ऐसा लगता है कि यह एक मौजूदा फ़ाइल को ओवरराइट नहीं करेगा। यदि यह मौजूद है तो यह सिर्फ इसे छोड़ देगा। – digitalsanctum

+0

... वास्तव में यह मौजूद फ़ाइलों को छोड़ देता है। पोस्ट करने से पहले उस विशेष उपयोग-मामले का परीक्षण न करने के लिए मुझे कितना मूर्खतापूर्ण है। मैं क्षमाप्रार्थी हूं। कृपया मेरा संपादित संस्करण देखें जो गंतव्य निर्देशिका को हटा देगा यदि यह पहले से मौजूद है। – bernie

+0

और मेरा दूसरा समाधान उप-शीर्ष भी था। क्योंकि पूरी निर्देशिका को हटाने शायद शायद ही कभी सलाह दी जाती है; लेकिन मेरा मानना ​​है कि तीसरा समय एक आकर्षण है: मैंने फाइल को हटाने के लिए थोड़ा सा कोड जोड़ा है यदि यह नई फाइल लिखने से पहले मौजूद है। – bernie

14

बस दूसरों मुसीबत को बचाने के लिए:

निकालने आदेश जवाब 2 में गलत है:

तिहाई (proc) पैरामीटर को एम्परसैंड wtih निर्दिष्ट किया जाता है, जिसका अर्थ है माणिक उम्मीद उस में होना करने के लिए {} - इस तरह विधि कॉल के बाद कोष्ठक:

zipfile.extract(entry, "#{target}/#{entry}"){ true } 

या (यदि आप और अधिक जटिल तर्क की जरूरत है)

zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) } 

यदि आप पोस्ट # 2 में दिए गए उदाहरण का उपयोग करते हैं तो आपको "अवैध तर्क (2 के लिए 3)" त्रुटि मिलेगी ...

+0

धन्यवाद। मैं रूबी के लिए नया हूं और एक घंटे के लिए इस विशेष दीवार के खिलाफ अपने सिर को हराया। –

0

यह link here एक अच्छा उदाहरण प्रदान करता है जिसे मैंने सत्यापित किया है। बस इसमें 'fileutils' की आवश्यकता होती है।