Ruby で tar.gz を扱う
Ruby で tar.gz を扱う方法を調べたところ、archive-tar-minitar というライブラリと zlib の組合せが簡単そうでした。
archive-tar-minitar | RubyGems.org | your community gem host
http://rubygems.org/gems/archive-tar-minitar
というわけで使ってみたメモなど。
インストール
% gem install archive-tar-minitar
複数ファイルを tar.gz にまとめる
圧縮自体は zlib の GzipWriter を使います。
# -*- coding: utf-8 -*- require 'zlib' require 'archive/tar/minitar' Zlib::GzipWriter.open('foo.tar.gz', Zlib::BEST_COMPRESSION) do |gz| out = Archive::Tar::Minitar::Output.new(gz) Find.find(File.expand_path('~/testdata/')) do |file| Archive::Tar::Minitar::pack_file(file, out) end out.close end
tar.gz を展開する
展開する場合は GzipReader と組み合わせて使います。
# -*- coding: utf-8 -*- require 'zlib' require 'archive/tar/minitar' Zlib::GzipReader.open('foo.tar.gz') do |gz| Archive::Tar::Minitar::unpack(gz, './foo') end
tar.gz にファイルのパスを含めないようにする
上の方法で圧縮した場合、圧縮する際にファイルのフルパスを指定すると、展開する際にも中間のディレクトリが作成されてしまうようです。
これを回避するため、一旦カレントディレクトリを変更し、圧縮後に戻すようにしてみました。
他にもっといい方法があるのかもしれませんが・・・。
# -*- coding: utf-8 -*- require 'zlib' require 'archive/tar/minitar' # 圧縮対象のディレクトリ DIR_PATH = "~/testdata" # 圧縮ファイルのパス ARCHIVE_PATH = "/home/akishin/work/foo.tar.gz" # カレントディレクトリを保存 current_dir = Dir::pwd # カレントディレクトリを変更 Dir::chdir(File.expand_path(DIR_PATH)) Zlib::GzipWriter.open(ARCHIVE_PATH, Zlib::BEST_COMPRESSION) do |gz| out = Archive::Tar::Minitar::Output.new(gz) Dir.glob('./*') do |file| Archive::Tar::Minitar::pack_file(file, out) end out.close end # カレントディレクトリを復元 Dir::chdir(current_dir)
こんな感じで結構簡単に tar.gz 形式を扱う事ができました。