Frage

Ich versuche, eine binäre Datei mit dem folgenden Code zu lesen:

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;

Die Eingabedatei ist 16M; die debug.txt ist nur etwa 400k. Als ich bei debug.txt in emacs schauen, sind die letzten zwei Zeichen sind ^ A ^ C (SOH und ETX Zeichen nach Notepad ++), obwohl das gleiche Muster in der debug.txt vorhanden ist. Die nächste Zeile in der Datei einen hat ^ O (SI) char, und ich denke, das ist das erste Auftreten dieses besonderen Charakters.

Wie kann ich in dieser ganzen Datei lesen?

War es hilfreich?

Lösung

Wenn Sie wirklich wollen auf einmal die gesamte Datei zu lesen, verwenden Sie schlürfen Modus. Slurp Modus kann durch Einstellen $/ eingeschaltet werden, um undef (die der Eingangsdatensatztrennzeichen ist). Dies wird am besten in einem separaten Block durchgeführt, so dass Sie Schlamassel nicht bis $/ für einen anderen Code.

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;

Verwenden my $data für eine lexikalische und our $data für eine globale Variable.

Andere Tipps

TIMTOWTDI .

File::Slurp ist der kürzeste Weg, auszudrücken, was Sie erreichen wollen. Es hat auch eine eingebaute Fehlerprüfung.

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

Das IO::File API löst das globale Variable $/ Problem in eleganter Art und Weise.

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

Ich glaube nicht, dass dies zu schlürfen Modus oder nicht, aber über den Umgang mit richtig Binärdateien.

statt

$data = <F>;

Sie tun sollten,

read(F, $buffer, 1024);

Dies wird nur 1024 Bytes lesen, so dass Sie den Puffer erhöhen müssen oder die gesamte Datei Teil für Teil lesen mit einer Schleife.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top