Ruby Zip

Gem позволяющий работать с данными, упакованными Zip, а так же сам создавать архивы.

Установка

На гитхабе рекомендуют использовать не только основной гем, но и интерфейс, который оставляет старое API.

gem install rubyzip zip-zip

Использование

В скриптах подключаем следующи образом:

require 'zip'

И переходим непосредственно к использованию

Конфигурирование

Zip.setup do |c|
  # Продолжать если файл в архиве уже есть
  c.on_exists_proc = false
  # Перезаписать файл в архиве
  c.continue_on_exists_proc = false
  # Имена с Unicode
  c.unicode_names = false
  # Степень сжатия (Zlib::BEST_COMPRESSION | Zlib::DEFAULT_COMPRESSION | Zlib::NO_COMPRESSION)
  c.default_compression = Zlib::DEFAULT_COMPRESSION
end

Создание архива

def create(archive, files)
  Zip::File.open(archive, Zip::File::CREATE) do |zip|
    files.each do |file|
      zip.add(file.sub(/^\//,''),file)
    end
  end
end

Просмотр содержимого

def listing(archive)
  Zip::File.open(archive) do |zip|
    zip.each do |file|
      puts file
    end
  end
end

Извлечение

А вот тут всё не так просто. Gem сам не создаёт вложенные директории, поэтому придётся подсуетиться

def extract(archive, prefix)
  require 'fileutils'
  FileUtils.mkdir_p(prefix) unless Dir.exists? prefix
 
  zip = Zip::File.open(archive)
  zip.each do |f|
    dst_file = "#{prefix}/#{f}".gsub(/\/[\/]+/, '/')
    dst_dir = File.dirname(dst_file)
    FileUtils.mkdir_p dst_dir unless Dir.exists? dst_dir
 
    puts "Extract #{f}"
    f.extract(dst_file)
  end
end

Чтение непосредственно из архива

def read(archive, file)
  zip = Zip::File.open(archive)
 
  file.gsub!(/^\//,'')
 
  entry = zip.glob(file)
  entry.each do |f|
    puts f.name
    puts f.get_input_stream.read
  end
end