3

次のコードでバイナリファイルを読み込もうとしています。

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を見ると、最後の2文字は^ A ^ C(notepad ++によるとSOHおよびETX文字)ですが、同じパターンがdebug.txtに存在します。ファイルの次の行には^O(SI)文字が含まれており、これがその特定の文字の最初の出現だと思います。

このファイル全体をどのように読み取ることができますか?

4

3 に答える 3

5

本当にファイル全体を一度に読みたい場合は、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グローバル変数に使用します。

于 2010-08-17T13:33:38.227 に答える
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::FileAPIは、グローバル変数の$/問題をより洗練された方法で解決します。

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);
}
于 2010-08-17T14:05:19.053 に答える
0

これはslurpモードを使用するかどうかではなく、バイナリファイルを正しく処理することについてだと思います。

それ以外の

$data = <F>;

やったほうがいい

read(F, $buffer, 1024);

これは1024バイトしか読み取らないため、バッファを増やすか、ループを使用してファイル全体を部分的に読み取る必要があります。

于 2013-10-31T15:40:18.890 に答える