YoDar YoDar - 7 months ago 20
Perl Question

How do I unpack binary files with Perl?

I have two binary files equal in size, but not in values. I used unpack as follows, but the results are weird.

When I use "big" binary files, both of the outputs shows part of the results:

One binary file starts good - ends bad,

Second binary file goes wrong at the start.

Where do you think may be the weak point?

open(BIN_FILE1, "<bin_files/BINF1.bin") or die("Cannot open file for writing");
open(BIN_FILE2, "<bin_files/BINF2.bin") or die("Cannot open file for writing");
binmode(BIN_FILE1);
binmode(BIN_FILE2);
# N An unsigned long (32-bit) in "network" (big-endian) order.
my @values_tmp1 = unpack("N*", <BIN_FILE1>);
my @values_tmp2 = unpack("N*", <BIN_FILE2>);
close (BIN_FILE1);
close (BIN_FILE2);
my $tmp_bin1 = @values_tmp1;
my $tmp_bin2 = @values_tmp2;
print "\nBIN FILE1 LENGTH: ",$tmp_bin1,"\n";
print "\nBIN FILE2 LENGTH: ",$tmp_bin2,"\n";


The output is:


BIN FILE1 LENGTH: 1203

BIN FILE2 LENGTH: 124


The input files are:

-rw-rw-r-- 1 yodar yodar 9600 2009-12-23 19:59 BINF1.bin
-rw-rw-r-- 1 yodar yodar 9600 2009-12-27 16:38 BINF2.bin


If there is another simple and safe way to gather binary files data to an array I'll be glad to know.

Answer

I suspect that you are not reading the entire file (the <> operator tries to read a record, using the record seperator $/ which is newline by default). Try changing the read to something like this:

{
    # Enable slurp mode
    local $/;
    my @values_tmp1 =  unpack("N*", <BIN_FILE1>);
    my @values_tmp2 =  unpack("N*", <BIN_FILE2>);
}