37 Stimmen

Wie kann ich eine Binärdatei in Perl erstellen?

Ich möchte zum Beispiel eine Datei namens sample.bin und geben Sie eine Zahl ein, z. B. 255, so dass 255 in der Datei als Little-Endian, FF 00, gespeichert wird. Oder 3826 bis F2 0E.

Ich habe versucht, binmode zu verwenden, wie in der Perldoc beschrieben.

0 Stimmen

Ich denke, der wichtigste Hinweis ist der Satz in perldoc von print : Druckt eine Zeichenkette oder eine Liste von Zeichenketten. ... und nicht Zahlen . Ich bin auch schon in diese Falle getappt.

44voto

Adam Batkin Punkte 49295

Die Perl packen Funktion gibt "binäre" Daten entsprechend einer Vorlage zurück.

open(my $out, '>:raw', 'sample.bin') or die "Unable to open: $!";
print $out pack('s<', 255);
close($out);

Im obigen Beispiel ist die 's' sagt ihm, dass es eine short (16 Bit), und die '<' erzwingt den Little-Endian-Modus.

Darüber hinaus, ':raw' beim Aufruf von open weist es an, den Filehandle auf Plattformen, auf denen das wichtig ist, in den Binärmodus zu versetzen (dies entspricht der Verwendung von binmode ). Die Website PerlIO Handbuchseite finden Sie weitere Informationen zur Durchführung von E/A in verschiedenen Formaten.

10voto

daotoad Punkte 26089

Sie können verwenden pack um Ihre binären Daten zu erzeugen. Für komplexe Strukturen, Umwandeln::Binär::C ist besonders schön.

CBC parst C-Header-Dateien (entweder aus einem Verzeichnis oder aus einer Variable in Ihrem Skript). Es verwendet die Informationen aus den Headern, um pack o unpack binäre Daten.

Wenn Sie dieses Modul verwenden wollen, sind natürlich C-Kenntnisse hilfreich.

CBC gibt Ihnen die Möglichkeit, die Endianness und Größen für Ihre C-Typen festzulegen, und Sie können sogar Funktionen zur Konvertierung zwischen nativen Perl-Typen und den Daten in der Binärdatei angeben. Ich habe diese Funktion für die Kodierung und Dekodierung von Festkommazahlen verwendet.

Für Ihr sehr einfaches Beispiel würden Sie verwenden:

use strict;
use warnings;

use IO::File; 

use Convert::Binary::C;

my $c = Convert::Binary::C->new('ByteOrder' => 'LittleEndian');

my $packed = $c->pack( 'short int', 0xFF );

print $packed;

my $fh = IO::File->new( 'outfile', '>' ) 
  or die "Unable to open outfile - $!\n";

$fh->binmode;

$fh->print( $packed );

CBC kommt in diesem Beispiel nicht wirklich zur Geltung, da es nur mit einem einzigen kurzen int arbeitet. Wenn Sie mit komplexen Strukturen arbeiten müssen, deren Typendefinitionen aus mehreren verschiedenen C-Headern stammen, werden Sie froh sein, dieses Werkzeug zur Hand zu haben.

Da Sie neu in Perl sind, schlage ich vor, dass Sie immer use stict et use warnings . Außerdem können Sie use diagnostics um genauere Erklärungen zu Fehlermeldungen zu erhalten. Sowohl diese Website als auch Perlmonke haben viele gute Informationen für Anfänger und viele sehr kluge, erfahrene Leute, die bereit sind, Ihnen zu helfen.

Übrigens, wenn Sie sich für den Weg der pack Route, sehen Sie sich die Anleitung zum Packen Es hilft, die etwas rätselhafte Packungsdokumentation zu verstehen.

6voto

pavium Punkte 14270

Ja, binmode verwenden

Für Ihr Unterhaltung (wenn nicht Bildung ) mein allererster Versuch, eine Binärdatei zu erstellen, beinhaltete binmode STDOUT und die folgenden:

sub output_word {
    $word = $_[0];
    $lsb  = $word % 256;
    $msb  = int($word/256);
    print OUT chr($lsb) . chr($msb);
    return $word;
} 

BENUTZEN SIE DIESEN CODE BITTE NICHT! Es stammt aus einer Zeit, in der ich es nicht besser wusste.

Man könnte argumentieren, dass ich das immer noch nicht tue, aber es wird hier wiedergegeben, um zu zeigen, dass Sie kann die Reihenfolge der Bytes zu kontrollieren, selbst mit hirntoten Methoden, und weil ich etwas gestehen muss.

Eine bessere Methode wäre die Verwendung von pack como Adam Batkin vorgeschlagen.

Ich glaube, ich habe die obige Untat in Perl 4 begangen. Das ist schon lange her. Ich wünschte, ich könnte es vergessen...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X