http://d.hatena.ne.jp/toku_bass/20110716#1310844437
Archive::Zipを使ってzipデータを解凍する場合、必ずファイルに書き出す必要があると思っていましたが、IO::String を使えば、zipデータを直接、解凍できるみたい。
※一方、圧縮(ZIP)に IO::String は必要なく、addString() , writeToFileNamed() でOK
http://search.cpan.org/perldoc?Archive%3A%3AZip
以下は、sample script
#!/usr/local/bin/perl use strict; use IO::String; use Archive::Zip qw/:ERROR_CODES/; my $UNZIP_DATA =<<EOF; 123457890ABCDEFGHIJKLMNOPQRSTUVWXYZ123457890ABCDEFGHIJKLMNOPQRSTUVWXYZ 123457890ABCDEFGHIJKLMNOPQRSTUVWXYZ123457890ABCDEFGHIJKLMNOPQRSTUVWXYZ 123457890ABCDEFGHIJKLMNOPQRSTUVWXYZ123457890ABCDEFGHIJKLMNOPQRSTUVWXYZ EOF my $ZIP_FILE_NAME = 'archive_zip_test.zip'; main(); sub main { zip_data($UNZIP_DATA,$ZIP_FILE_NAME); unzip_data($ZIP_FILE_NAME); } sub zip_data { my ($unzip_data,$zip_file_name) = @_; my $zip = Archive::Zip->new(); #ZIP(圧縮) $zip->addString( $unzip_data, 'UNZIP_TEST.TXT'); unless ( $zip->writeToFileNamed($zip_file_name) == AZ_OK ) { die "can't writeToFileNamed( $zip_file_name ): $!"; } } sub unzip_data { my ($zip_file_name) = @_; my $zip = Archive::Zip->new(); my $zip_data; open(my $fh,"<",$zip_file_name) or die "can't open $zip_file_name : $!"; { local $/ = undef; $zip_data = <$fh>; } close($fh) or die "can't close $zip_file_name : $!"; unless($zip->readFromFileHandle(IO::String->new($zip_data)) == AZ_OK){ die "can't readFromFileHandle(): $!"; } #UNZIP(解凍) for my $member ($zip->members) { print $zip->extractMember($member); } }
zip圧縮の結果を標準出力(STDOUT)へ出力
http://search.cpan.org/perldoc?Archive%3A%3AZip
cpanにも記載されていますが、具体的には「*STDOUT」をファイルハンドルとして利用することで可能です。
sub stdout_ziped_file { my ($self,$seikyu_no) = @_; my $m_zip = $self->zip_all_denpyo($seikyu_no); my $basename = join('_','請求書セット',$seikyu_no); print $self->get_http_download_header("$basename.ZIP", "application/zip"); my $stdout = *STDOUT; $m_zip->writeToFileHandle($stdout, 0); return $self; } sub zip_all_denpyo { my ($self,$seikyu_no) = @_; my $p_seikyu = Sing::PrintXls::Seikyu->new($self->{dbh},$self->{user}); my $saved_dir = $p_seikyu->get_print_out_dir($seikyu_no,'NO_MAKE_DIR'); my @denpyo_paths; for my $filename ( qw/kakeuri_seikyu.xls kakeuri_seikyu_hikae.xls kakeuri_seikyu_nyukin_hikae.xls/ ){ my $denpyo_name = $p_seikyu->get_denpyo_name($filename); my $file_path = join('/',$saved_dir,$filename); next if (not -e $file_path); push(@denpyo_paths,[$file_path,$denpyo_name]); } return undef if @denpyo_paths == 0; my $zip = Archive::Zip->new(); for my $denpyo_path ( @denpyo_paths ){ $zip->addFile($denpyo_path->[0],encode('cp932',$denpyo_path->[1])); } return $zip; }
その他関連エントリ
パスワード(暗号化)非対応なArchive::Zipは /usr/bin/zip, unzipで代用
└ http://d.hatena.ne.jp/end0tknr/20090214/1234567839
unzipの-p オプションでunzipの結果を標準出力へ
└ http://d.hatena.ne.jp/end0tknr/20110926/1317013278
zipファイルをhttp getし、zip解凍後、プレビュー表示
└ http://d.hatena.ne.jp/end0tknr/20110109/1294582088