我有两个大小相等的二进制文件,但没有值。我使用unpack如下,但结果很奇怪。
当我使用“大”二进制文件时,两个输出都显示部分结果:
一个二进制文件开始很好 - 结束不好,
第二个二进制文件在开始时出错。
你认为哪里可能是弱点?
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";
输出结果为:
BIN FILE1 LENGTH:1203
BIN FILE2 LENGTH:124
输入文件为:
-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
如果有另一种简单而安全的方法将二进制文件数据收集到数组中,我将很高兴知道。
答案 0 :(得分:9)
我怀疑你没有读取整个文件(<>
运算符尝试使用记录分隔符$ /默认为换行符读取记录)。尝试将读取更改为以下内容:
{
# Enable slurp mode
local $/;
my @values_tmp1 = unpack("N*", <BIN_FILE1>);
my @values_tmp2 = unpack("N*", <BIN_FILE2>);
}
答案 1 :(得分:6)
你说你有“大”文件。看起来它们并不是那么大,并且很容易适应记忆。
但是,如果您的文件太大而无法一次性存储在内存中,则可以使用read
或sysread
来读取数据块中的数据。
示例 - 一次读入4000个字节:
my $file_path = 'bin_files/BINF1.bin';
open my $fh, '<:encoding(raw)', $file_path
or die "Cannot open file '$file_path' for reading";
my $buffer;
while ( my $got = read( $fh, $buffer, 4000 ) ) {
warn "Read $got bytes from file\n."
my @integers = unpack "N*", $buffer;
do_stuff( \@integers );
$buffer = '';
}
使用带有词法句柄的3参数open
,它可以避免某些安全性和可维护性问题。 3 arg open
还允许您在mode标志中指定文件编码。这样你就不需要调用binmode了。