【问题标题】:Problems reading a binary file with ActivePerl?使用 ActivePerl 读取二进制文件时出现问题?
【发布时间】:2011-03-30 23:53:38
【问题描述】:

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

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

如何阅读整个文件?

【问题讨论】:

  • $data = ;获取 $data = do { undef $/; };

标签: perl binaryfiles activestate


【解决方案1】:

如果您真的想一次读取整个文件,请使用 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】:

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】:

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

而不是

$data = <F>;

你应该这样做

read(F, $buffer, 1024);

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    相关资源
    最近更新 更多