All formats

rubyzip

LanguageRuby (3.0+ for rubyzip 3.x)
LicenseBSD 2-clause
Repositorygithub.com/rubyzip/rubyzip
DocumentationREADME, API docs
Depends onRuby's bundled zlib
Read / writeyes / yes, ZIP64, stored and DEFLATE, AES (read 3.1+, write 3.7+) and ZipCrypto

rubyzip has two APIs:

Version 3.0 changed optional arguments to keyword arguments (create: true, destination_directory:), so code written for 2.x needs small changes.

Installation#

Shell
gem install rubyzip

Or in a Gemfile:

Ruby
gem "rubyzip", "~> 3.0"

Basic usage: extract a ZIP file#

Ruby
require "zip"

MAX_SIZE = 100 * 1024 * 1024  # refuse entries larger than 100 MB

Zip::File.open("in.zip") do |zip|
  zip.each do |entry|
    puts "#{entry.name} #{entry.size} bytes"
    raise "#{entry.name} too large" if entry.size > MAX_SIZE
  end

  # writes every entry under out/, creating folders;
  # names that would land outside out/ are skipped with a warning
  zip.extract_all("out")
end

To extract a single entry use entry.extract(destination_directory: "out", create_parent_directories: true); without that option, current versions don’t create missing parent folders.

How to create a ZIP file#

Ruby
require "zip"

Zip::File.open("out.zip", create: true) do |zip|
  zip.add("docs/report.pdf", "report.pdf")    # name in archive, file on disk
  zip.get_output_stream("hello.txt") { |f| f.write "hello from Ruby\n" }
end

How to read one file from a ZIP#

Ruby
require "zip"

Zip::File.open("in.zip") do |zip|
  entry = zip.find_entry("docs/readme.txt")
  puts entry.get_input_stream.read if entry

  # or by pattern
  zip.glob("*.csv").each { |e| puts e.name }
end

How to create a ZIP in memory#

Ruby
require "zip"

buffer = Zip::OutputStream.write_buffer do |out|
  out.put_next_entry("report.csv")
  out.write "id,name\n1,Alice\n"
end
data = buffer.string  # the ZIP bytes, e.g. for send_data in Rails

How to create and read an AES-encrypted ZIP#

Ruby
require "zip"

enc = Zip::AESEncrypter.new("my password", Zip::AESEncryption::STRENGTH_256_BIT)
Zip::OutputStream.open("secret.zip", encrypter: enc) do |out|
  out.put_next_entry("secret.txt")
  out.write "top secret"
end

dec = Zip::AESDecrypter.new("my password", Zip::AESEncryption::STRENGTH_256_BIT)
Zip::InputStream.open("secret.zip", decrypter: dec) do |input|
  while (entry = input.get_next_entry)
    puts "#{entry.name}: #{input.read}"
  end
end

For ZipCrypto use Zip::TraditionalEncrypter / Zip::TraditionalDecrypter with just the password.

Tips#