SyntaxHighlighter

2013年10月27日日曜日

SevenZipRuby - Ruby 用 7zip gem ライブラリ

SevenZipRuby - Ruby 用 7zip gem ライブラリ

Ruby の C 拡張機能や、 gem ライブラリ作成の勉強をしようと思ったので、 7-Zip のアーカイブを読み書きする拡張ライブラリを作成しました。
まだ開発中で、どこまで作り込むかは不明ですが、とりあえず GitHub に公開しました。
seven_zip_ruby にあるので、興味がありましたらご覧ください。

なお、 API の仕様などは、これから変更されていくだろうと思います。

そこまで深く調べていないので、似たようなライブラリが既にあるかもしれません。

サンプル

README.md にもありますが、以下のように使うことができます。ただし、これは 2013/10/27 時点での API に基づいています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 7zip アーカイブの展開
File.open("filename.7z", "rb") do |file|
  SevenZipRuby::Reader.open(file) do |szr|
    szr.extract_all "path_to_dir"
  end
end
 
# アーカイブ内のファイル情報の表示
File.open("filename.7z", "rb") do |file|
  SevenZipRuby::Reader.open(file) do |szr|
    list = szr.entries
    p list
    # => [ "[Dir: 0: dir/subdir]", "[File: 1: dir/file.txt]", ... ]
  end
end
 
# パスワードで暗号化されたアーカイブの展開
File.open("filename.7z", "rb") do |file|
  SevenZipRuby::Reader.open(file, { password: "Password String" }) do |szr|
    szr.extract_all "path_to_dir"
  end
end
 
# 圧縮
File.open("filename.7z", "wb") do |file|
  SevenZipRuby::Writer.open(file) do |szr|
    szr.add_file "entry1.txt"
    szr.mkdir "dir1"
    szr.add_buffer "entry2.txt", "binary_data 123456"
  end
end

概要

オフィシャルにリリースされている 7-Zip の DLL である 7z.dll を内部的に呼び出しています。

7zip 圧縮などでは、マルチスレッドで動作します。このあたりの挙動は 7z.dll の挙動に依存します。

Windows, Linux で動作する (はず) です。 Mac OSX はいずれ対応するだろうと思います。

gem にしてありますが、 rubygems にはまだ登録してません。
やったことがないので、まだ方法もよく分かってませんが、いずれ登録します。

作成のポイント

7z.dll の API では、コールバック関数を DLL に登録し、それを適宜呼び出してもらうようになっています。
このコールバック関数の呼び出しは、場合によっては 7z.dll 内で生成された別スレッドから行われることもあります。
これは、 GIL や GVL と呼ばれる Ruby Interpreter の Mutex を持っていない状態でコールバックが呼ばれるということを意味します。
この動作に対応するのが面倒でした。

また、 C++ で作成したので、こちらもやや面倒でした。

これらについては、別途、まとめておこうと思います。