Thursday Night

Paul Betts’s personal website / blog / what-have-you

Extracting a zip file in Ruby

comments

I just spent like 2 hours trying to get this damn piece of code to work – trying to extract a zip file to a temporary directory. Most of my problems were because of the lack of documentation in rubyzip, but the end result appears to work. Here it is, obviously you need the abovementioned library from Rubygems.

[‘rubygems’, ‘pathname’, ‘zip/zip’].each {|x| require x}

UUIDchars = ("a".."f").to_a + ("0".."9").to_a
def uuid_seg(len)
  ret = ""
  1.upto(len) { |i| ret < < UUIDchars[rand(UUIDchars.size-1)] }; ret
end

def random_uuid
  "#{uuid_seg(8)}-#{uuid_seg(4)}-#{uuid_seg(4)}-#{uuid_seg(4)}-#{uuid_seg(12)}"
end

def extract_zip_to_tempdir(zip_path)
  temp_root = Pathname.new((ENV[‘TEMP’] || ENV[‘TMP’] || ‘/tmp’))
  raise "Can’t find a temp directory" unless temp_root.exist?

  # Figure out our temp directory
  temp_dir = nil
  while (temp_dir = temp_root.join(random_uuid())).exist?
    nil
  end
  temp_dir.mkpath

  ZipFile.open(zip_path) do |zf|
    zf.each do |e|
      if (m = /^(.*)[\\\/][^\\\/]*$/.match(e.name))
        temp_dir.join(m[1]).mkpath
      end
      zf.extract(e.name, File.join(temp_dir.to_s, e.name))
    end
  end

  temp_dir.to_s
end

Written by Paul Betts

July 29th, 2007 at 3:21 am

Posted in Ruby

Leave a Reply