2009-09-23 15 views
32

Ad esempio, desidero creare un file denominato sample.bin e inserire un numero, ad esempio 255, in modo che 255 venga salvato nel file come little-endian, FF 00. Oppure da 3826 a F2 0E.Come posso creare un file binario in Perl?

Ho provato a utilizzare binmode, come detto perldoc.

+2

Cosa c'è di sbagliato in voi persone che qualcuno abbia effettivamente votato questa domanda? –

+0

Penso che la mia grammatica non sia buona e non ben strutturata. – domlao

+1

+1 per offset -1, quello ed è Perl. Sensazione soggettiva. : D –

risposta

38

La funzione perl pack restituirà i dati "binari" in base a un modello.

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

Nell'esempio precedente, il 's' dice di uscita un short (16 bit), e le forze '<' sulla modalità little endian.

Inoltre, ':raw' nella chiamata a open dice di mettere il filehandle in modalità binaria su piattaforme in cui quello che conta (che equivale a utilizzare binmode). La pagina di manuale PerlIO ha un po 'più di informazioni su come eseguire I/O in diversi formati.

+0

wow, vedo grazie. Im nuovo a PERL quindi penso che visiterò perldoc per la funzione di pacchetto. grazie – domlao

+0

pack è una bella funzione. Presta particolare attenzione ai caratteri del template per codificare i valori little-endian vs. big-endian – mob

+0

grazie ad Adam e mobrule. il pacchetto è perfetto! grazie – domlao

4

Sì, uso binmode

Per il vostro intrattenimento (se non educazione) il mio primo tentativo di creare un file binario incluso binmode STDOUT e la seguente:

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

per pietà NON UTILIZZARE QUESTO CODICE! Viene da un tempo in cui non sapevo di meglio.

Si potrebbe sostenere che ancora non lo faccio, ma è riprodotto qui per dimostrare che si può controllare l'ordine dei byte, anche con metodi di morte cerebrale, e perché ho bisogno di 'fess up.

Un metodo migliore sarebbe utilizzare pack come Adam Batkin suggerito.

Penso di aver commesso l'atrocità di cui sopra in Perl 4. E 'stato tanto tempo fa. Vorrei poterlo dimenticare ...

+3

Ho guardato a un vecchio codice di recente ho pensato che fosse fantastico. Era una schifezza, e io non avevo fatto molta programmazione nei due anni che mi toccavano. Ho letto da qualche parte che se non pensi che il tuo vecchio codice sia schifoso, allora c'è qualcosa di sbagliato in te. .... vorrei ricordare, è stato un grande articolo. –

+1

Mille grazie a chi mi ha messo in subbuglio. Ora posso cancellare il file sorgente a cui sono aggrappato e il processo di guarigione può iniziare. – pavium

+1

Se la risposta non ti piace, puoi eliminarla. –

8

È possibile utilizzare pack per generare i dati binari. Per le strutture complesse, Convert::Binary::C è particolarmente bello.

CBC analizza i file di intestazione C (da una directory o da una variabile nello script). Utilizza le informazioni dalle intestazioni ai dati binari pack o unpack.

Naturalmente, se si desidera utilizzare questo modulo, è utile conoscere un po 'di C.

CBC ti dà la possibilità di specificare l'endianness e formati per i tipi di C, e si può anche specificare le funzioni per la conversione tra tipi nativi di Perl e i dati nel file binario. Ho usato questa funzione per gestire la codifica e la decodifica dei numeri a virgola fissa.

Per esempio molto semplice devi usare:

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 in realtà non arriva a brillare in questo esempio, dal momento che è solo lavorando con un unico short int.Se hai bisogno di gestire strutture complesse che potrebbero avere typedefs estratti da diverse intestazioni C diverse, sarai molto felice di avere questo strumento a portata di mano.

Dato che sei nuovo in Perl, ti suggerisco di sempre use stict e use warnings. Inoltre, è possibile use diagnostics per ottenere spiegazioni più dettagliate per i messaggi di errore. Sia questo sito che lo Perlmonks hanno molte buone informazioni per i principianti e molte persone molto intelligenti e competenti che desiderano aiutarvi.

BTW, se si decide di percorrere il percorso pack, controllare lo pack tutorial, aiuta a chiarire la documentazione del pacchetto un po 'mistificante.

+0

grazie per i suggerimenti e per il collegamento tutorial pack :) – domlao

Problemi correlati