Ruby/ZIP で圧縮解凍

Ruby/ZIP で圧縮解凍

バージョンと製造年月日

  • 2009年06月11日
  • WindowsXP SP3
  • Ruby 1.8.6

zipruby版

rubyzipよりもzipruby版をオススメします。インタフェースが素直です。

Zip/Ruby - Ruby bindings for libzip.

解凍

require 'zipruby'
require 'fileutils'
 
def ore_unzip(src_path, output_path)
  output_path = (output_path + "/").sub("//", "/")
  Zip::Archive.open(src_path) do |archives|
    archives.each do |a|
      d = File.dirname(a.name)
      FileUtils.makedirs(output_path + d)
      unless a.directory?
        File.open(a.name, "w+b") do |f|
          f.print(a.read)
        end
      end
    end
  end
end
 
ore_unzip("hoge.zip", ".")

rubyzip 版

インストール

例のごとくgemで一発

$ gem install rubyzip

ファイル圧縮

簡単

require 'rubygems'
require 'zip/zipfilesystem'
 
def ore_zip(src_path, output_path)
  src_path = File.expand_path(src_path)
  output_path = File.expand_path(output_path)
  Zip::ZipFile.open(output_path, Zip::ZipFile::CREATE) do |zip_file|
    zip_file.add(File.basename(src_path), src_path)
  end
end
 
ore_zip('piyo.txt', 'piyo.zip')

このライブラリマニュアルを眺めると・・・Javaっぽいよね。Rubyっぽくなくてなんか嫌だw ってかJavaの移植って書いてあった。改めてダメ

複数ファイル圧縮

ガンガンaddすれば出力されるみたいです

require 'rubygems'
require 'zip/zipfilesystem'
 
def ore_zip(src_paths, output_path)
  output_path = File.expand_path(output_path)
  Zip::ZipFile.open(output_path, Zip::ZipFile::CREATE) do |zip_file|
    src_paths.each do |src_path|
      src_path = File.expand_path(src_path)
      zip_file.add(File.basename(src_path), src_path)
    end
  end
end
 
ore_zip(['piyo1.txt', 'piyo2.txt'], 'piyo.zip')

圧縮(ブロック使わない版)

ブロック構文を使いたくないときもありますわな

require 'rubygems'
require 'zip/zipfilesystem'
 
def ore_zip(src_paths, output_path)
  output_path = File.expand_path(output_path)
  zip_file = Zip::ZipFile.new(output_path, Zip::ZipFile::CREATE)
  src_paths.each do |src_path|
    src_path = File.expand_path(src_path)
    zip_file.add(File.basename(src_path), src_path)
  end
  zip_file.close()
end
 
ore_zip(['piyo1.txt', 'piyo2.txt'], 'piyo.zip')

解凍

これで解凍できるんだが・・・

require 'zip/zipfilesystem'
require 'fileutils'
 
def ore_unzip(src_path, output_path)
  output_path = (output_path + "/").sub("//", "/")
  Zip::ZipInputStream.open(src_path) do |s|
    while f = s.get_next_entry()
      d = File.dirname(f.name)
      FileUtils.makedirs(output_path + d)
      f =  output_path + f.name
      unless f.match(/\/$/)
        p f
        File.open(f, "w+b") do |wf|
          wf.puts(s.read())
        end
      end
    end
  end
end
 
ore_unzip("hoge.zip", ".")

このstreamの扱いがどうもキモイなんでentryから値を抽出しないで、streamから取得するような設計になっているのだろうか??Java脳?

参考サイト

Tags

ruby/zip_archive.txt · 最終更新: 2021-12-31 16:59 by ore