How to overwrite existing files with Rubyzip lib

I am trying to unzip a file with several files that may or may not exist in the destination directory. The default behavior seems to be throwing an exception if the file already exists.

How to unzip to a directory and just overwrite existing files?

Here is my code:

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 
+7
ruby unzip
source share
4 answers

It seems that extract () accepts an optional block (onExistsProc), which allows you to determine what to do with the file, if it already exists, return true to overwrite, false to throw an exception.

If you want to simply overwrite all existing files, you can do:

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

If you want to make more complex logic for processing certain records in different ways, you can do:

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

EDIT: fixed answer - as Ingmar Hamer pointed out, my original answer passed the block as a parameter when it expected to use the above syntax.

+12
source share

Just to save others, the problem is:

The extract command in answer 2 is incorrect:

The third parameter (proc) is set with an ampersand, that is, the ruby ​​expects it to be in {} -Brackets after calling the method as follows:

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

or (if you need more complex logic)

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

If you use the example specified in Post # 2, you will get "invalid arguments (3 for 2)" error ...

+14
source share

Edit: Modified code to delete the target file if it exists in advance.

 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') 

Edit: Modified code to delete the target directory, if it exists in advance.

 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') 

Here is the source 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') 
+1
source share
0
source share

All Articles