Я хочу прочитать большой двоичный файл (500 МБ) и получить определенные байты, расположенные после заголовка, который повторяется каждые 5000 байт. Для этого у меня есть короткий фрагмент, читающий файл в двоичном режиме и размером блока 16536.
Код работает по назначению, но съедает всю доступную память, что делает его непригодным для использования. Я пытался закрыть и открыть проанализированный выходной файл, в который я пишу каждый раз, когда должна быть выполнена операция записи, но это не помогает. Может ли проблема быть связана с тем, как я читаю двоичный файл?
Вот мой код:
use strict;
my $BLOCK_SIZE=16536;
my $fname = $ARGV[0];
my $fparsename = $ARGV[1];
open(F,"<$fname") or die("Unable to open file $fname, $!");
binmode(F);
my $buf;
my $ct=0;
my $byte=0;
my $byte_old=0;
my $byte_cnt=0;
my $byte_lock=0;
my $sample_msb=0;
my $sample_lsb=0;
my $sample_16b=0;
my $out_form='';
open(my $fh, '>', $fparsename) or die "Could not open file '$fparsename' $!";
print $fh ("Sample, Value \n");
close($fh);
while(read(F,$buf,$BLOCK_SIZE,$ct*$BLOCK_SIZE)){
foreach(split(//, $buf)){
$byte_old = $byte;
$byte = ord($_); # fetch byte (in decimal)
if (($byte_old == 202) && ($byte == 254)) { # CA = 202, FE = 254
$byte_cnt = 0;
$byte_lock = 1;
}
if ($byte_lock == 1) {
$byte_cnt++;
}
if ($byte_cnt == 20) { # 20th byte after CAFE in header
$sample_msb = $byte;
}
if ($byte_cnt == 21) { # 21th byte after CAFE in header
$sample_lsb = $byte;
}
if (($byte_cnt == 21) && ($byte_lock == 1)) { # lock down and concatenate
$byte_lock = 0;
$byte_cnt = 0;
$sample_16b = sprintf("%X", $sample_msb) . sprintf("%X", $sample_lsb);
$out_form = sprintf("%d, %s \n", $ct++, $sample_16b);
open(my $fh, '>>', $fparsename) or die "Could not open file '$fparsename' $!";
printf $fh $out_form;
close($fh);
}
}
$ct++;
}
close(F);
close($fh);
CA = 202, FE = 254
, вы должны использовать0xCA
и0xFE
. - person Borodin   schedule 15.02.2017