【问题标题】:How do I unpack binary files with Perl?如何用 Perl 解压二进制文件?
【发布时间】:2016-05-01 19:18:36
【问题描述】:

我有两个大小相等但值不同的二进制文件。我使用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 文件 1 长度:1203

BIN 文件 2 长度: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

如果有另一种简单且安全的方法将二进制文件数据收集到数组中,我会很高兴知道。

【问题讨论】:

    标签: perl


    【解决方案1】:

    我怀疑您没有读取整个文件(&lt;&gt; 运算符尝试读取记录,使用记录分隔符 $/ 默认为换行符)。尝试将读取更改为如下内容:

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

    【讨论】:

    • 是的,这可以解决问题。谢谢哈斯昆。
    【解决方案2】:

    你说你有“大”文件。看起来它们并没有那么大,而且很容易放入内存中。

    但是,如果您的文件太大而无法一次全部放入内存,您可以使用readsysread 分块读取数据。

    示例 - 一次读取 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 还允许您在模式标志中指定文件编码。这样你就不需要调用 binmode。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      相关资源
      最近更新 更多