ここで唯一難しいのは、入力ファイルと出力ファイルの両方がバイナリ モードで読み込まれるようにすることです。これは:raw
、ファイルを開くときに PerlIO レイヤーを使用することで実現できます。
このプログラムは、あなたが望むことをするようです。最初にインデックス ブロックを検索して文字列に読み取り、次にその文字列を入力用に開き、各構成ファイルの開始位置と終了位置、および名前を読み取ります。その後の各ファイルの処理は簡単です。
ランダムなテキストにはスペースが含まれる可能性があるため、インデックス ブロックの書式設定があなたが言うよりも厳密でない限り、各行の最初、2 番目、および最後の空白で区切られたフィールドのみに頼ることができることに注意してください。また、スペースを含むファイル名を指定する方法もありません。
を使用した出力は、Data::Dump
正しい機能を示すためのものであり、プログラムの機能には必要ありません。
use v5.10;
use warnings;
use Fcntl ':seek';
use autodie qw/ open read seek close /;
open my $fh, '<:raw', 'container.bin';
read $fh, my $index_loc, 6;
seek $fh, $index_loc, SEEK_SET;
read $fh, my ($index), 1024;
my %contents;
open my $idx, '<', \$index;
while (<$idx>) {
my @fields = split;
next unless @fields;
$contents{$fields[-1]} = [ $fields[0], $fields[1] ];
}
use Data::Dump;
dd \%contents;
for my $file (keys %contents) {
my ($start, $end) = @{ $contents{$file} };
my $size = $end - $start;
seek $fh, $start, SEEK_SET;
my $nbytes = read $fh, my ($data), $size;
die "Premature EOF" unless $nbytes == $size;
open my $out, '>:raw', $file;
print { $out } $data;
close $out;
}
出力
{
"Capture.PNG" => [6, 15149],
"index.php" => [15149, 15168],
"untilted.tga" => [15168, 211794],
}