2009-09-23 8 views
32

Par exemple, je veux créer un fichier appelé sample.bin et mettre un nombre, comme 255, de sorte que 255 est enregistré dans le fichier comme little-endian, FF 00. Ou 3826 à F2 0E.Comment puis-je créer un fichier binaire en Perl?

J'ai essayé d'utiliser binmode, comme l'a dit le perldoc.

+2

Qu'est-ce qui ne va pas chez vous si quelqu'un a réellement rejeté cette question? –

+0

Je pense que ma grammaire n'est pas très bonne et pas bien structurée. – domlao

+1

+1 pour compenser -1, ça et c'est Perl. Se sentir subjectif. : D –

Répondre

38

La fonction perl pack retournera des données "binaires" selon un modèle.

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

Dans l'exemple ci-dessus, le 's' il indique à la sortie d'un short (16 bits), et les forces '<' le en mode petit-boutiste.

En outre, ':raw' dans l'appel à open dit à mettre le descripteur de fichier en mode binaire sur les plateformes où ce qui compte (il équivaut à utiliser binmode). La page de manuel PerlIO contient un peu plus d'information pour faire des E/S en différents formats.

+0

wow je vois merci. im nouveau à PERL donc je pense que je vais visiter perldoc pour la fonction pack. merci – domlao

+0

pack est une fonction agréable. Portez une attention particulière aux caractères du modèle pour coder les valeurs little-endian et big-endian – mob

+0

merci Adam et mobrule. le pack est parfait! merci – domlao

4

Oui, l'utilisation binmode

Pour votre divertissement (sinon éducation) ma première tentative de création d'un fichier binaire inclus binmode STDOUT et les éléments suivants:

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

AU NOM DE PITIÉ N'UTILISEZ PAS CE CODE! Ça vient d'une époque où je ne connaissais pas mieux. On pourrait argumenter que je ne le fais toujours pas, mais il est reproduit ici pour montrer que vous pouvez contrôler l'ordre des octets, même avec des méthodes cérébrales, et parce que j'ai besoin de fesser.

Une meilleure méthode serait d'utiliser pack comme Adam Batkin suggéré.

Je pense que j'ai commis l'atrocité ci-dessus dans Perl 4. C'était il y a longtemps. J'aimerais pouvoir l'oublier ...

+3

J'ai regardé à un ancien code pensant récemment que c'était génial. C'était de la merde, et je n'avais pas fait beaucoup de programmation depuis deux ans. J'ai lu quelque part que si vous ne pensez pas que votre ancien code est de la merde alors il y a quelque chose qui ne va pas chez vous. .... J'aimerais me souvenir, c'était un bon article. –

+1

Un grand merci à celui qui m'a mis à jour. Je peux maintenant supprimer le fichier source auquel je suis resté, et le processus de guérison peut commencer. – pavium

+1

Si vous n'aimez pas votre réponse, vous pouvez la supprimer. –

8

Vous pouvez utiliser pack pour générer vos données binaires. Pour les structures complexes, Convert::Binary::C est particulièrement agréable. CBC analyse les fichiers d'en-tête C (provenant d'un répertoire ou d'une variable de votre script). Il utilise les informations des en-têtes à pack ou unpack des données binaires.

Bien sûr, si vous voulez utiliser ce module, il est utile de connaître quelques C.

CBC vous donne la possibilité de spécifier le boutisme et tailles pour vos types C, et vous pouvez même spécifier des fonctions pour convertir entre les types Perl natifs et les données dans le fichier binaire. J'ai utilisé cette fonctionnalité pour gérer l'encodage et le décodage des nombres à virgule fixe.

Pour votre exemple de base que vous utiliseriez:

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 n'a pas vraiment de briller dans cet exemple, car il est juste de travailler avec un short int.Si vous avez besoin de gérer des structures complexes qui peuvent avoir des typedefs tirés de plusieurs en-têtes C différents, vous serez très heureux d'avoir cet outil à portée de main. Comme vous êtes nouveau à Perl, je vais vous suggérer toujours use stict et use warnings. En outre, vous pouvez use diagnostics pour obtenir des explications plus détaillées sur les messages d'erreur. Ce site et Perlmonks ont beaucoup de bonnes informations pour les débutants et beaucoup de gens très intelligents et qualifiés prêts à vous aider.

BTW, si vous décidez d'aller le pack route, consultez le pack tutorial, il permet de clarifier la documentation de l'emballage quelque peu mystificateur.

+0

merci pour les conseils, et pour le lien tutoriel pack :) – domlao

Questions connexes