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

时间:2010-08-17 13:30:22

标签: perl binaryfiles activestate

我正在尝试使用以下代码读取二进制文件:

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字符,根据记事本++),尽管debug.txt中存在相同的模式。文件中的下一行确实有一个^ O(SI)字符,我认为这是该特定字符的第一次出现。

我如何阅读整个文件?

3 个答案:

答案 0 :(得分:5)

如果确实想要立即读取整个文件,请使用slurp模式。通过将$/(输入记录分隔符)设置为undef,可以打开Slurp模式。这最好在一个单独的块中完成,这样您就不会为其他代码搞砸$/

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表示全局变量。

答案 1 :(得分:3)

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);
}

答案 2 :(得分:0)

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

而不是

$data = <F>;

你应该做

read(F, $buffer, 1024);

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