In Perl wordt de interactie met bestanden georganiseerd door bestandsdescriptoren te openen met behulp van open. Naast de standaarddescriptors (STDIN, STDOUT, STDERR) kunnen gebruikers ook hun eigen descriptors aanmaken en beheren.
Perl gebruikt het concept van invoer- en uitvoerlagen (:encoding, :utf8, :raw, enz.) om verschillende bestands- en coderingssoorten correct te verwerken. Standaard kan Perl werken in tekstmodus (met regelovergangen) of binaire modus.
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;
De juiste keuze van de laag (:raw voor binaire bestanden, :encoding(NAME) voor tekstbestanden) zorgt voor correcte lees- en schrijfoperaties.
Als je een bestand opent met de constructie
open FH, '<', $fileen binaire gegevens leest, krijgen we altijd een correct resultaat?
Antwoord: Nee! Zonder de opgave van :raw zal Perl op sommige platforms automatisch regelovergangsymbolen omzetten (bijvoorbeeld, CRLF → LF op Windows). Gebruik altijd de :raw modus voor het lezen van binaire bestanden:
open my $fh, '<:raw', 'file.bin';
Verhaal
In een bedrijfsproject werkten ontwikkelaars met tekstbestanden, waarbij ze regels zonder expliciete codering lazen. Hierdoor 'braken' de logs in UTF-8 soms, omdat het gelezen bestand beschadigd was bij het lezen van Cyrillische symbolen, aangezien Perl de bytes verkeerd interpreteerde. De fout werd pas verholpen na de expliciete toevoeging van de laag
:encoding(UTF-8)aan deopenaanroep.
Verhaal
Op Windows, bij het kopiëren van binaire bestanden, lazen ze gegevens met
open FH, '<', 'binfile.dat'en schreven ze zonder de modus aan te geven. Het programma 'brak' afbeeldingen, omdat in de regelovergangstroom CRLF werd omgezet naar LF, wat leidde tot ongeldige binaire gegevens. De laag:rawloste het probleem op.
Verhaal
In een externe API was alleen uitvoer op STDOUT in UTF-8 vereist, maar de programmeurs gebruikten
binmode STDOUT, ':encoding(UTF-8)'verdween het probleem.