En Perl, l'ouverture de descripteurs pour travailler avec des fichiers se fait en utilisant open. En plus des descripteurs standard (STDIN, STDOUT, STDERR), vous pouvez créer vos propres descripteurs et les gérer.
Perl utilise le concept de couches d'entrée-sortie (:encoding, :utf8, :raw, etc.) pour traiter correctement différents types de fichiers et encodages. Par défaut, Perl peut fonctionner en mode texte (avec translation de lignes) ou binaire.
open my $fh, '<:encoding(UTF-8)', 'file.txt' or die $!; while (my $line = <$fh>) { print $line; } close $fh;
open my $fh, '<:raw', 'image.bin' or die $!; read($fh, my $data, -s 'image.bin'); close $fh;
Le choix correct de la couche (:raw pour binaire, :encoding(NAME) pour textuel) assure une lecture et une écriture correctes.
Si vous ouvrez un fichier en utilisant la construction
open FH, '<', $fileet que vous lisez des données binaires, obtiendrons-nous toujours un résultat correct ?
Réponse : Non ! Sans l'indication :raw, Perl sur certaines plateformes modifiera automatiquement les caractères de translation de ligne (par exemple, CRLF → LF sur Windows). Pour lire des fichiers binaires, utilisez toujours le mode :raw:
open my $fh, '<:raw', 'file.bin';
Histoire
Dans un projet d'entreprise, les développeurs ont travaillé avec des journaux texte, en lisant des lignes sans spécifier l'encodage. En conséquence, les journaux en UTF-8 étaient parfois "coupés" — le fichier lu était corrompu lors de la lecture de caractères cyrilliques, car Perl interprétait mal les octets. L'erreur n'a été corrigée qu'après avoir ajouté explicitement la couche
:encoding(UTF-8)dans l'appel àopen.
Histoire
Sous Windows, lors de la copie de fichiers binaires, ils ont lu les données avec
open FH, '<', 'binfile.dat'et les ont écrites sans indiquer le mode. Le programme "casse" les images, car dans le flux de translation de lignes, CRLF était remplacé par LF, ce qui conduisait à des données binaires invalides. La couche:rawa corrigé le problème.
Histoire
Dans une API externe, il était nécessaire que la sortie STDOUT soit uniquement en UTF-8, mais les programmeurs utilisaient
binmode STDOUT, ':encoding(UTF-8)', le problème a disparu.