Come sovrascrivere i file esistenti utilizzando Rubyzip lib
Domanda
sto cercando di decomprimere un file con diversi file che possono o non possono esistere già nella directory di destinazione. Sembra che il comportamento predefinito è quello di generare un'eccezione se il file esiste già.
Come faccio a decomprimere in una directory e semplicemente sovrascrivere i file esistenti?
Ecco il mio codice:
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
Soluzione
Sembra che l'estratto () prende un blocco opzionale (onExistsProc) che consente di determinare cosa fare con il file se esiste già -. Ritorni vero per sovrascrivere, false per sollevare un'eccezione
Se si voleva semplicemente sovrascrivere tutti i file esistenti, si potrebbe fare:
zipfile.extract(entry, "#{target}/#{entry}") { true }
Se si vuole fare un po 'logica più complessa da gestire voci specifiche in modo diverso, si può fare:
zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) }
EDIT:. risposta fisso - come ha sottolineato Ingmar Hamer, la mia risposta originale superato il blocco come parametro quando è previsto utilizzando la sintassi sopra
Altri suggerimenti
Proprio per salvare gli altri il problema:
Il comando estratto in risposta 2 non è corretta:
Il terzo parametro (proc) viene specificato addebbitato una e commerciale, il che significa rubino si aspetta che sia in {} -Brackets dopo la chiamata al metodo come questo:
zipfile.extract(entry, "#{target}/#{entry}"){ true }
o (se avete bisogno di una logica più complessa)
zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) }
Se si utilizza l'esempio dato in Post # 2 si otterrà un "argomenti non validi (3 per 2)" Errore di ...
Modifica:. Codice modificato per rimuovere file di destinazione, se esiste in anticipo
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')
Modifica:. Codice modificato per rimuovere directory di destinazione, se esiste in anticipo
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')
Ecco il codice originale da 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')
qui fornisce un buon esempio che ho verificato opere. Ha solo bisogno di avere un require 'fileutils' aggiunto ad esso.