Reading and Writing ZIP Files

Problem

You want to create or examine a ZIP archive from within Ruby code.

Solution

Use the rubyzip gem. Its Zip module gives you several ways of putting files into ZIP archives, and taking them out again. The simplest interface is the Zip::ZipFileSystem, which duplicates most of the File and Dir operations within the context of a ZIP file. You can use this to create ZIP files:

	require 
ubygems
	require zip/zipfilesystem

	Zip::ZipFile.open(zipfile.zip, Zip::ZipFile::CREATE) do |zip|
	 zip.file.open(file1, w) { |f1| f1 << This is file 1. }
	 zip.dir.mkdir(subdirectory)
	 zip.file.open(subdirectory/file2, w) { |f1| f1 << This is file 2. }
	end

You can use the same interface to read a ZIP file. Heres a method that uses the equivalent of Dir#foreach to recursively print out the contents of a ZIP file:

	def process_zipfile(zip, path=\)
	 if zip.file.file? path
	 puts %{#{path}: "#{zip.read(path)}"}
	 else
	 unless path.empty?
	 path += /
	 puts path
	 end
	 zip.dir.foreach(path) do |filename|
	 process_zipfile(zip, path + filename)
	 end
	 end
	end

And here it is running against the ZIP file I just created:

	Zip::ZipFile.open(zipfile.zip) do |zip|
	 process_zipfile(zip)
	end
	# subdirectory/
	# subdirectory/file2: "This is file 2."
	# file1: "This is file 1."

Discussion

ZIP, or PKZip, is the most popular compression format on Windows. As seen in the previous recipe, Unix separates the tasks of stuffing several files into a single archive (tar), and compressing the resulting file (gzip). On Windows, ZIP files perform both tasks. If you want to compress a single file, you need to put it into a ZIP file all by itself.

The rubyzip library provides several interfaces for creating and reading ZIP files. Zip::ZipFileSystem is the easiest for most programmers: in the example above, zip.file has about the same interface as the File class, and zip.dir is similar to the Dir class. The analogy holds because a ZIP file actually contains a tiny filesystem inside it.[5]

[5] This is how Windows XPs Explorer can let you browse a ZIP file as though it were a directory tree.

If you e porting Java code, or you e already familiar with Javas java.util.zip library, you might prefer the Zip::ZipFile class. It more or less duplicates Javas ZipFile class in a Ruby idiom. Here it is being used to create the same ZIP file I created in the Solution:

	Zip::ZipFile.open(zipfile2.zip, Zip::ZipFile::CREATE) do |zip|
	 zip.get_output_stream(file1) { |f| f << This is file 1. }
	 zip.mkdir(subdirectory)
	 zip.get_output_stream(subdirectory/file2) { |f| f << This is file 2. }
	end

See Also

  • The RDoc for the rubyzip gem (http://rubyzip.sourceforge.net/)


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net