代码之家  ›  专栏  ›  技术社区  ›  chris

用activeperl读取二进制文件时出现问题?

  •  3
  • chris  · 技术社区  · 14 年前

    我试图用以下代码读取二进制文件:

    open(F, "<$file") || die "Can't read $file: $!\n";
    binmode(F);
    $data = <F>;
    close F;
    
    open (D,">debug.txt");
    binmode(D);
    print D $data;
    close D;
    

    输入文件是16M;debug.txt只有400K左右。当我在emacs中查看debug.txt时,最后两个字符是^A^C(soh和etx字符,根据notepad++),尽管debug.txt中存在相同的模式。文件中的下一行确实有一个^o(s i)字符,我认为这是该特定字符的第一次出现。

    我如何才能读取整个文件?

    3 回复  |  直到 11 年前
        1
  •  5
  •   daxim Fayland Lam    14 年前

    如果你 真正地 要同时读取整个文件,请使用slurp模式。可以通过设置打开slurp模式 $/ (输入记录分隔符)到 undef . 最好是在一个单独的街区内完成,这样你就不会搞砸了。 美元/ 其他代码。

    my $data;
    {
        open my $input_handle, '<', $file or die "Cannot open $file for reading: $!\n";
        binmode $input_handle;
        local $/;
        $data = <$input_handle>;
        close $input_handle;
    }
    
    open $output_handle, '>', 'debug.txt' or die "Cannot open debug.txt for writing: $!\n";
    binmode $output_handle;
    print {$output_handle} $data;
    close $output_handle;
    

    使用 my $data 对于词汇和 our $data 对于全局变量。

        2
  •  3
  •   daxim Fayland Lam    14 年前

    TIMTOWTDI .

    File::Slurp 是表达你想要实现的目标的最短方式。它还具有内置的错误检查功能。

    use File::Slurp qw(read_file write_file);
    my $data = read_file($file, binmode => ':raw');
    write_file('debug.txt', {binmode => ':raw'}, $data);
    

    这个 IO::File API 求解全局变量 $/ 以更优雅的方式解决问题。

    use IO::File qw();
    my $data;
    {
        my $input_handle = IO::File->new($file, 'r') or die "could not open $file for reading: $!";
        $input_handle->binmode;
        $input_handle->input_record_separator(undef);
        $data = $input_handle->getline;
    }
    {
        my $output_handle = IO::File->new('debug.txt', 'w') or die "could not open debug.txt for writing: $!";
        $output_handle->binmode;
        $output_handle->print($data);
    }
    
        3
  •  0
  •   golimar    11 年前

    我认为这不是使用slurp模式,而是正确处理二进制文件。

    而不是

    $data = <F>;
    

    你应该做

    read(F, $buffer, 1024);
    

    这将只读取1024个字节,因此您必须增加缓冲区或使用循环一部分一部分地读取整个文件。