ファイルの読み込み開始位置と終了位置を指定して書き出す〜seek、read
●ポイント
◎seek([ファルハンドル], [起点からの位置(スタート地点になる)], [起点]); 起点は、0だとファイルの先頭、1だと現在の位置、2だとファイルの末尾になる。(0, 1, 2以外は入りません) 例), seek($fh, 20,0); →ファイルの先頭から20バイト進んだところが読み込み・書き込み位置になる。 ◎read([ファイルハンドル], [読み込んだ情報を格納するスカラー変数], [読み込む情報の終点])
●お題
こんな↓ファイル(test_yoko_ryouri.eps)があるとします。
プレビュー情報を読み取って、TIFFファイルのみを抽出して保存してください。
#! /usr/bin/perl use strict; use warnings; #何度もこのスクリプトを回して大丈夫なように、既に抽出したTIFFファイルがあるときは消去しておく system("rm copy_ryouri.tif") if -e "copy_ryouri.tif"; #epsファイルを読み取りモードで、書き出すTIFFファイルをcopy_ryouri.tifという名前でopenする open(my $fh,'<','test_yoko_ryouri.eps') || die "can't open (test_yoko_ryouri.eps)"; open(my $out,'>','copy_ryouri.tif') || die "can't open (copy_ryouri.tif)"; #プレビュー情報(ファイルの先頭から30バイト)を読み込む read ($fh, my $offset_info, 30); # my $offset_info = <$fh>; だと、一行読み込める。 #プレビュー情報から、TIFFファイルの開始位置とサイズを取得 my $start_point = substr($offset_info,20,4); my $size = substr($offset_info,24,4); #読み取った開始位置とサイズは、バイナリ情報のため変換する(バイナリファイルでなければしなくてよい) $start_point = unpack("v", $start_point); $size = unpack("v", $size); #ファイルの読み込み開始位置を指定 seek($fh, $start_point, 0); #指定した読み込み開始位置からTIFFファイルのサイズまでファイルを読み込む(TIFFファイルの抽出) read($fh, my $data, $size); #抽出したTIFFファイルの書き出し print $out $data; #ファイルをクローズ close($out); close($fh);
以下、参考になったサイトです。
■unpack
http://perl.misty.ne.jp/function02/unpack.html
■unpackで指定できる型指定文字列
http://perl.misty.ne.jp/function01/pack_option.html
短く書けないか、がんばってみた。もっと短く書く方法があったら教えてください。
#! /usr/bin/perl use strict; use warnings; system("rm copy_ryouri.tif") if -e "copy_ryouri.tif"; open(my $fh,'<','test_yoko_ryouri.eps') || die "can't open (test_yoko_ryouri.eps)"; open(my $out,'>','copy_ryouri.tif') || die "can't open (copy_ryouri.tif)"; my $offset_info = <$fh>; seek($fh, (unpack "v", (substr($offset_info, 20, 4))),0); read($fh, my $data, (unpack "v", (substr($offset_info,24,4)))); print $out $data; close($out); close($fh);