كيفية الكتابة فوق الملفات الموجودة باستخدام 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
المحلول
يبدو أن الاستخراج () يأخذ كتلة اختيارية (OnexistProc) يتيح لك تحديد ما يجب القيام به مع الملف إذا كان موجودا بالفعل - إرجاع True الكتابة فوق، False لرفع استثناء.
إذا كنت ترغب ببساطة الكتابة فوق جميع الملفات الموجودة، فيمكنك القيام به:
zipfile.extract(entry, "#{target}/#{entry}") { true }
إذا كنت ترغب في القيام بمنطق أكثر تعقيدا للتعامل مع إدخالات محددة بشكل مختلف، فيمكنك القيام به:
zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) }
تعديل: إجابة ثابتة - كما أشير عن طريق Ingmar Hamer، اجبت إجابتي الأصلية الكتلة كمعلمة عند توقعها باستخدام بناء الجملة أعلاه.
نصائح أخرى
فقط لإنقاذ الآخرين المشكلة:
أمر الاستخراج في الإجابة 2 غير صحيح:
تم تحديد المعلمة الثالثة (PROC) WTIH Ampersand، بمعنى Ruby تتوقع أن تكون في {}-Broknets بعد استدعاء الطريقة مثل هذا:
zipfile.extract(entry, "#{target}/#{entry}"){ true }
أو (إذا كنت بحاجة إلى منطق أكثر تعقيدا)
zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) }
إذا كنت تستخدم المثال الوارد في Post # 2، فستحصل على خطأ "حجج غير صالحة (3 لمدة 2)" ...
تحرير: تعديل التعليمات البرمجية لإزالة الملف الهدف إذا كان موجودا مسبقا.
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')
هنا الرمز الأصلي من مارك نيدهام:
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')
هذه الرابط هنا يوفر مثالا جيدا الذي قمت بالتحقق منه. يحتاج فقط إلى الحصول على طلب "fileutils" المضافة إليها.