こんにちは!システムエンジニアのオオイシです。
Rubyでzipファイルの圧縮や解凍方法を知っていますか?
rubyzipというライブラリを使えばRubyでzipファイルの作成や解凍が可能です。
この記事では、
- rubyzipをインストール
- ファイルをzip圧縮する
- zipファイルを解凍する
- パスワード付きzipファイルの作成する
- パスワード付きzipファイルの解凍する
といった基本的な内容から、
- ディレクトリを圧縮する
- 解凍せずにzipファイルを読み取る
- Rubyの文字列からzipファイルを作成する
などの応用的な使い方に関しても解説していきます!
今回はこれらの方法を覚えるために、Rubyでzipファイルを扱うためのさまざまな使い方をわかりやすく解説します!
rubyzipの使い方
rubyzipをインストールする
Rubyでzipファイルへの圧縮や解凍をするにはいくつかの手段がありますが、「rubyzip」というライブラリを使う方法が一般的なので、この方法について解説します。
まずはじめにrubyzipのgemをインストールしましょう。
gem install rubyzip
実行結果:
Fetching: rubyzip-1.2.1.gem (100%) Successfully installed rubyzip-1.2.1 Parsing documentation for rubyzip-1.2.1 Installing ri documentation for rubyzip-1.2.1 Done installing documentation for rubyzip after 0 seconds 1 gem installed
gemとは、Rubyのパッケージ管理システムです。
gemを知らない場合は、こちらで詳しく説明していますので参考にしてください。
では、次の項でさっそくzipファイルを扱ってみましょう!
ファイルをzip圧縮する
rubyzipには、zipファイルに圧縮するために使用する「Zip::OutputStream」クラスがあります。
「Zip::OutputStream」クラスの使い方のイメージは、zipファイルへ小川(Stream)が流れるように書き込みを行います。
ここでは、基本的な使い方を知っていただくために、1つのファイルをzip圧縮する方法をサンプルコードを交えて解説します。
サンプルプログラムで使うファイル構造は次のとおりです。
. ├── compress.rb ├── input │ └── file_name.txt └── zip_file.zip └── output └── file_name.txt
たくさんのファイルがありますが、丁寧に説明するのでご安心ください!
それぞれファイルの役割は次のようになります。
ファイル名 | 説明 |
---|---|
compress.rb | zipファイルを作成するサンプルプログラム |
input/file_name.txt | 圧縮元のテキストファイル |
zip_file.zip | プログラム実行後に作成されるzipファイル |
output/file_name.txt | zip_file.zipの中に圧縮されたファイル |
まずは、プログラムを実行する前準備として、圧縮元のテキストファイル(input/file_name.txt)を作成してください。
テキストファイルの内容は任意ですが、今回は次のようにしました。
1行目 2行目
それでは、”input/file_name.txt”の1つのファイルを”zip_file.zip”ファイルへ圧縮するサンプルプログラムを確認してみましょう。
require 'zip' file_name = "file_name.txt" zip_file_name = "zip_file.zip" # 作成するzipファイルのパスを引数に指定 Zip::OutputStream.open(zip_file_name) do |out| # zipファイル内に書き込むファイルのパスを指定 out.put_next_entry("output/" + file_name) # zipファイルへ文字列を書き込む buffer = File.read("input/" + file_name) out.write(buffer) end
実行してみましょう。
ruby compress.rb
実行した結果、”zip_file.zip“が作成されます。
このサンプルプログラムでは、
- out.put_next_entry(zipへ書き込むファイルのパス)
- out.write(zipへ書き込む内容)
で、2つのメソッドを使ってzipファイルへ書き込みができる点について解説しました。
「Zip::OutputStream」クラスのメソッドは次のようなものがあります。
メソッド名 | 用途・目的 |
---|---|
open | 圧縮するzipファイルのパスを引数に指定。 ブロックには「Zip::OutputStream」のインスタンス変数が渡る |
put_next_entry | zipファイルに登録するファイルパスを引数に指定 |
write | put_next_entryに指定したファイルパスに書き出す文字列を引数に指定 |
以降の説明は、この解説の応用になるので簡単にわかっていただけると思います!
また、サンプルプログラムの中で登場したFileクラスについては、こちらで詳しく説明していますのでぜひ参考にしてください。
zipファイルを解凍する
rubyzipでは、zipファイルを解凍するために「Zip::InputStream」クラスを使います。
「Zip::InputStream」クラスの使い方のイメージは、小川(Stream)が流れるようにzipファイルを読み込みます。
それでは、前項のプログラムで作成した”zip_file.zip”ファイルを解凍するサンプルプログラムについて解説していきます。
今回のファイル構造は次のようにしました。
. ├── uncompress.rb └── zip_file.zip └── output └── file_name.txt
それぞれファイルの役割は次のようになります。
ファイル名 | 説明 |
---|---|
uncompress.rb | zip_file.zipを解凍するサンプルプログラム |
zip_file.zip | 前項のサンプルプログラムで作成したzipファイル |
output/file_name.txt | zip_file.zipの中のテキストファイル |
それでは、サンプルプログラムを確認してみましょう。
require 'zip' zip_file_name = "zip_file.zip" # 解凍するzipファイルのパスを引数に指定 Zip::InputStream.open(zip_file_name) do |input| # 次に取得できるzip内のファイル情報を取得 entry = input.get_next_entry # 解凍するディレクトリを作成する Dir.mkdir(File.dirname(entry.name)) # entry.nameでzipファイルのパスを取得 file_name = entry.name # zip内ファイルの内容を読み込み buffer = input.read # ファイルに書き出し File.write(file_name, buffer) end
実行してみましょう。
ruby uncompress.rb
実行した結果、”1行目<改行>2行目“という内容テキストファイルが”output/file_name.txt”に作成されました。
このサンプルプログラムでは、
- input.get_next_entry → zip内で取得可能なファイルの情報を取得
- input.read → ファイルの読み出し
の2つのメソッドを使ってzipファイルを解凍できることを解説しました。
「Zip::InputStream」クラスの代表的なメソッドは次のとおりです。
メソッド名 | 用途・目的 |
---|---|
open | 解凍するzipファイルのパスを第1引数に指定 |
get_next_entry | zipファイル内のファイル情報を返す |
read | zipファイル内のデータを読み取り返す |
また、サンプルプログラムの中で登場したDirクラスについては、こちらで詳しく説明していますので、ぜひ参考にしてください。
パスワード付きzipファイルを取り扱うには
パスワード付きzipファイルの作成
rubyzipではパスワード付きのzipファイルを作成することができます。
セキュリティー上の理由からzipファイルにパスワードを付与することは、いまや常識となっているので、ここで覚えておくと何かと役に立ちます!
そんなパスワードつきのzipファイルの作成も、これまでの解説の応用なので作成はとってもカンタンです!
require 'zip' file_name = "file_name.txt" zip_file_name = "password_zip_file.zip" # zipパスワードを作成 password = Zip::TraditionalEncrypter.new('password') # 第2引数にパスワードを指定 Zip::OutputStream.open(zip_file_name, password) do |out| out.put_next_entry("output/" + file_name) out.print("1行目\n") out.print("2行目\n") end
このプログラムを実行した結果、パスワード付きの”password_zip_file.zip“ファイルが作成されます。
次は、Rubyプログラムでパスワードつきのzipファイルを解凍する解説をします。
パスワード付きzipファイルの解凍
rubyzipではパスワード付きのzipファイルを解凍することができます。
前項で作成した、パスワード付きzipファイルの”password_zip_file.zip”を解凍するサンプルプログラムを確認してみましょう。
require 'zip' zip_file_name = "password_zip_file.zip" # zipパスワードを作成 password = Zip::TraditionalDecrypter.new('password') # 第3引数にパスワードを指定、第2引数は0固定 Zip::InputStream.open(zip_file_name, 0, password) do |input| entry = input.get_next_entry Dir.mkdir(File.dirname(entry.name)) File.write(entry.name, input.read) end
実行した結果、パスワード付きzipが解凍されて”output/file_name.txt”にファイルが出来上がります。
このように「Zip::InputStream.open」メソッドの第3引数にパスワードを指定するだけで、パスワード付きzipファイルを、カンタンに解凍するできることが理解いただけたと思います!
また、サンプルプログラム中のDir.mkdirメソッドについてはこちらで詳しく説明していますので、ぜひ参考にしてください。
ディレクトリを圧縮する
ディレクトリ内の全てのファイルを含んだzipファイルを作成する方法を確認してみましょう。
今までの解説で登場した「Zip::OutputStream」クラスを使った応用ですので、新しいことを覚えずに実現できます。
このサンプルプログラムでは”input_dir”フォルダ内の全てのファイルを”input_dir.zip”ファイルへ圧縮する例です。
プログラムを実行する前には”input_dir”フォルダへ圧縮したい任意のファイルをコピーするなどして準備しておいてください。
require 'zip' zip_file_name = "input_dir.zip" #input_dirフォルダ内のファイル名を配列に登録 entries = Dir.glob("input_dir/*") Zip::OutputStream.open(zip_file_name) do |out| # input_dirフォルダ内のファイル名のループ entries.each do |entry| # ファイルパスのうち、ファイル名のみを取得する file_name = File.basename(entry) # zip内にファイル名と内容を登録 out.put_next_entry("output_dir/" + file_name) out.write( File.read(entry) ) end end
実行した結果、”input_dir.zip“が作成されるので、ソフトで解凍してファイルの内容を確認してみてください。
解凍せずにzipファイルを読み取る方法
rubyzipでは、zipファイルを解凍せずにzip内のファイルを読み込むことが可能です。
zip内のテキストファイルを読み取るには、1行ごとに文字列を取得するために使用するeach_lineメソッドを使うと便利です。
前章のサンプルで作成した”zip_file.zip“内のテキストファイルを読み取るサンプルプログラムを確認してみましょう。
require 'zip' zip_file_name = "zip_file.zip" # 読み取るzipファイルのパスを引数に指定 Zip::InputStream.open(zip_file_name) do |input| # zip内のファイル情報を取得 entry = input.get_next_entry puts "zip内のファイルパス: #{entry.name}" # zip内のファイルを改行コード毎にループ input.each_line do |line| puts line end end
実行結果:
zip内のファイルパス: output/file_name.txt 1行目 2行目
このように、”zip_file.zip“ファイル内の”output/file_name.txt”の内容を読み取って、putsメソッドで出力することができました。
each_lineメソッドを使うと、zip内のテキストファイルを改行毎に処理できることがわかっていただけたと思います!
each_lineメソッド以外にも、Rubyプログラムで使える次のような便利なメソッドがあるので、ぜひ使ってみてください!
メソッド名 | 用途・目的 |
---|---|
each_line | ファイル内の文字列を行毎に読み取り、ブロックの変数に渡す |
readlines | ファイル内の文字列を行毎に読み取り、配列で返す |
read | 画像や文字列などのバイナリデータを読み取る |
文字列からzipファイルを作成する
rubyzipではRubyプログラムからzipファイルへ直接書き込むことができます。
今まで解説したサンプルプログラムの応用なのでカンタンに実現することできます。
zipファイルに2つのテキストファイルを作成し、文字列を書き込むサンプルプログラムを確認してみましょう。
require 'zip' file_name1 = "file_name1.txt" file_name2 = "file_name2.txt" zip_file_name = "zip_file.zip" Zip::OutputStream.open(zip_file_name) do |out| # zip_file.zip内の output/file_name1.txt へ書き込み out.put_next_entry("output/" + file_name1) out.print("#{file_name1} 1行目\n") out.print("#{file_name1} 2行目\n") # zip_file.zip内の output/file_name2.txt へ書き込み out.put_next_entry("output/" + file_name2) out.print("#{file_name2} 1行目\n") out.print("#{file_name2} 2行目\n") end
実行した結果、”zip_file.zip“ファイルが作成できるので、ソフトで解凍すると、次のようなファイルが作成されています。
output/file_name1.txt:
file_name1.txt 1行目 file_name1.txt 2行目
output/file_name2.txt:
file_name2.txt 1行目 file_name2.txt 2行目
このように、Rubyプログラム内からzipファイルを作成できることができました。
その他にもzip内のファイルへ書き出すために、次のような便利なメソッドがあります。
メソッド名 | 説明 |
---|---|
引数に指定した文字列または配列をzip内のファイルに出力 | |
puts | printメソッドと同様。違いは改行コードを行末に自動挿入 |
printf | 第1引数に指定した書式で、2引数の文字列をzip内のファイルに出力 |
putc | 引数に指定した1文字または1桁の整数をzip内のファイルに出力 |
write | 引数に指定した文字列や画像などのバイナリデータをzip内のファイルに出力 |
また、printfメソッドの書式についてはこちらで詳しく説明していますので、ぜひ参考にしてください。
まとめ
いかかでしたか?
今回はrubyzipを使ったzipファイルへの圧縮や解凍方法の使い方について説明しました。
rubyzipを使うとパスワード付きのzipファイルの作成や解凍を処理することが可能です。
rubyzipを使うとプログラム内からzipファイルの読み取りや書き込みしたい場合に大変便利になので、ぜひ活用してください。
そして、rubyzipの使い方を忘れてしまったらこの記事を確認してくださいね!