Как перезаписать существующие файлы, используя Rubyzip lib - PullRequest
8 голосов
/ 08 июня 2009

Я пытаюсь разархивировать файл с несколькими файлами, которые могут или не могут уже существовать в целевом каталоге. Кажется, по умолчанию выдается исключение, если файл уже существует.

Как разархивировать в каталог и просто перезаписать существующие файлы?

Вот мой код:

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

Ответы [ 4 ]

15 голосов
/ 09 июня 2009

Похоже, что extract () принимает необязательный блок (onExistsProc), который позволяет вам определить, что делать с файлом, если он уже существует - вернуть true для перезаписи, false для вызова исключения.

Если вы хотите просто перезаписать все существующие файлы, вы можете сделать:

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

Если вы хотите сделать более сложную логику для обработки определенных записей по-разному, вы можете сделать:

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

РЕДАКТИРОВАТЬ: фиксированный ответ - как указал Ингмар Хамер, мой оригинальный ответ передал блок в качестве параметра, когда ожидается, что с использованием вышеуказанного синтаксиса.

15 голосов
/ 09 октября 2009

Просто чтобы избавить других от неприятностей:

Команда извлечения в ответе 2 неверна:

Третий параметр (proc) указывается с амперсандом, что означает, что ruby ​​ожидает, что он будет в {} -Brackets после вызова метода, подобного этому:

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

или (если вам нужна более сложная логика)

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

Если вы воспользуетесь примером, приведенным в Посте № 2, вы получите ошибку «Недопустимые аргументы (3 для 2)» ...

1 голос
/ 08 июня 2009

Редактировать: Модифицированный код для удаления целевого файла, если он существует заранее.

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')
0 голосов
/ 12 апреля 2010

Эта ссылка здесь предоставляет хороший пример, который я проверял, работает. Просто нужно добавить требуемый fileutils.

...