トップページ >  perl >  Perl Archive::Zipを使用してファイルの圧縮を行う
初版2012/03/09: 最終更新日2012/03/09
Perl Archive::Zipを使用してファイルの圧縮を行う
目次
概要
Archive::Zipモジュールのインストール
ファイル名の扱い
絶対パス、相対パスでの圧縮の差
圧縮の実行
ソースサンプル
概要
./sampledir/ 以下に次のようなファイルが存在する場合。

./sampledir/aaaa.txt
./sampledir/サンプル1.txt
./sampledir/あいうえお.txt

環境は Linux上で文字コードはUTF-8とする。

上記のファイルをsampledirフォルダごと圧縮する方法を記載します。

Archive::Zipモジュールのインストー
使用するモジュールがインストールされている事を確認します。

shell> perl -MArchive::Zip

このように入力し、エラーが出なければモジュールがインストールされています。
(入力待ち状態となりますので、 Ctrl + c や Ctrl + d で抜けてください)

インストールされていない場合は、下記のようなエラーが出力されます。


Can't locate Archive/Zip.pm in @INC (@INC contains: /usr/lib/perl5/si......

インストールされていた方は、この章を読み飛ばして結構です。


それでは、Archive::Zipモジュールのインストールを開始します。
インストールは、Perl のモジュール群が登録されているCPANから行います。

rootユーザになります

shell> su -


cpan コマンドを入力します
shell# cpan

そうすると、cpanシェルが立ち上がり下記のような画面が表示されます。

cpan shell -- CPAN exploration and modules installation (v1.7602)
ReadLine support available (try 'install Bundle::CPAN')

cpan>


cpanシェルにて Archive::Zipモジュールをインストールします。

cpan> install Archive::Zip

インストールが成功すると、最後に下記のように表示されます。

/usr/bin/make install -- OK


これでインストールは完了します。
ファイル名の扱い
ファイル名が英数字など、Linux上でもWindows上でも同じように扱える場合は良いのですが、
日本語を含むファイル名を扱いたい場合、
今回のようにLinux上で圧縮したZIPファイルを、Windows上へ移動して解凍した場合に、
ファイル名が文字化けを起こしてしまいます。

この際に利用するのが、Encode.pm です。

こちらを用い、ファイル名をWindowsで扱えるように「Shift-JIS」へ変換します。

# このようにコード中に記載し、Encode.pm の利用を宣言します。
use Encode;

# Linux 上で utf-8として扱っているファイル名を、
# perl内部文字コードへ変換します

my $string = decode('utf8', './sampledir/サンプル1.txt');

# perl内部文字コードへ変換したファイル名を
# Shift-JISへ変換します

my $encoded_filename = encode('shiftjis', $string);

これで、Shift-JISでのファイル名が完成しました。
絶対パス、相対パスでの圧縮の差
今回のようなファイルを圧縮する場合、
相対パスで下記のように指定して圧縮を行えば、
解凍先でも同じようなファイル構成で展開されます。

▼相対パス指定
./sampledir/サンプル1.txt



しかし、絶対パス指定をした場合、
解凍時にも指定したディレクトリ構成の部分へファイル展開を行うため、
別環境(Linux -> Windows)へZIPファイルを移動して解凍した場合、
エラーとなってしまいます。

▼絶対パス指定
/path/to/sampledir/サンプル1.txt

圧縮の実行
Archive::Zip を利用してファイルの圧縮を行います。

# 利用準備をします。
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );


# ZIPのオフじぇくとを生成。
my $zip = Archive::Zip->new()


# 圧縮を行うファイルの追加のやり方
# ファイルのパスは圧縮したいディレクトリ名を相対パスで指定
$zip->addFile('./sampledir/aaaa.txt');


# 日本語のファイル名を含む場合は、
# 先ほどのやり方で Shift-JISにしたファイル名を、
# 解凍時に利用してもらうように、第二引数として渡します。

$zip->addFile('./sampledir/サンプル1.txt', $encoded_filename);


全ての圧縮対象ファイルを追加し終えましたら、
圧縮を行います。

$zip->writeToFileNamed('圧縮した後のファイル名.zip', 'zip');

こちらの処理は、成功すると AZ_OK の値が返ってきます。


今までの事を利用し、
日本語ファイル名のファイルを含むZIPファイルを作成するサンプルを次に記します。
ソースサンプル
#!/usr/bin/perl
#
use strict;
use Encode;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );

use Data::Dumper;

# 圧縮対象ファイルは分かっているものとし、 # ファイル名を記載しておく my @filelist = qw(
./tmp/hoge.txt
./tmp/あああ.txt
./tmp/あいうえお.txt
);

my $zip = Archive::Zip->new();


for my $filename (@filelist) {
# 日本語ファイル名対応 my $string = decode('utf8', $filename);
my $encoded_filename = encode('shiftjis', $string);

# 圧縮対象ファイルを追加、第二引数に解凍後のファイル名を追加
$zip->addFile($filename, $encoded_filename);
}

# 出来上がるファイル名を指定
my $filename = 'sampledir.zip';

if ($zip->writeToFileNamed($filename, 'zip') == AZ_OK) {
print "OK", "\n";
} else {
print "NG", "\n";

}