Geschiedenis van de vraag:
Perl is oorspronkelijk ontwikkeld als een hulpmiddel voor efficiënte verwerking van tekststromen, waardoor de mechanismen voor invoer/uitvoer (I/O) tot de meest verfijnde in de kern van de taal behoren. Met de ontwikkeling van Unicode en de opkomst van verschillende lagen van invoer en uitvoer is de taak om de juiste codering te kiezen en het beheer van stromen te controleren relevant geworden om verlies of beschadiging van gegevens te voorkomen.
Probleem:
Onjuist gekozen codering bij het lezen/schrijven van bestanden leidt tot vervorming van gegevens (vooral met nationale tekens), en fouten in het beheer van stromen (bijvoorbeeld het niet controleren van het succesvolle openen van bestanden) worden vaak de oorzaak van bugs en kwetsbaarheden.
Oplossing:
Voor het openen van bestanden wordt open met een driedelige syntaxis gebruikt, wat veiliger en universeler is (voorkomt kwetsbaarheden bij de interpretatie van paden en modi). Voor correcte interactie met coderingen worden lagen toegepast (bijvoorbeeld "<:encoding(UTF-8)"). Het is altijd noodzakelijk om de succesvolle opening/sluiting te controleren en expliciet de benodigde werkmodi in te stellen.
Voorbeeld:
open my $fh, '<:encoding(UTF-8)', $filename or die "Kan $filename niet openen: $!"; while (my $line = <$fh>) { chomp $line; # verwijdert nieuwe regel print "$line "; } close $fh or warn "Kan $filename niet sluiten: $!";
Belangrijke kenmerken:
Kan je gebruikersinvoer rechtstreeks doorgeven aan open zonder controle?
Antwoord: Nee! Dit leidt tot kwetsbaarheden (bijvoorbeeld het uitvoeren van shell-opdrachten bij een onveilige alias) en fouten bij het werken met paden. Gebruik de expliciete driedelige syntaxis.
Wat gebeurt er als je geen laag codering opgeeft, maar het bestand is in UTF-8?
Antwoord: Perl zal proberen de bytes als latin1 te interpreteren, wat zal leiden tot vervormde tekens bij uitvoer/lezing, vooral als nationale alfabetten worden gebruikt.
Is het voldoende om gewoon close aan te roepen om ervoor te zorgen dat het bestand correct is geschreven?
Antwoord: Nee. Na close moet je de teruggegeven waarde controleren. Als er een fout is opgetreden bij het schrijven, zal Perl dit alleen melden via $! na een onsuccesvolle close. Bijvoorbeeld:
close $fh or die "Schrijven mislukt: $!";
De loghandler leest het bestand via open FILE, "file.txt", controleert het succes niet, verwerkt de gegevens op byte-niveau — als resultaat worden Cyrilische symbolen omgevormd tot abracadabra, sommige regels gaan verloren.
Voordelen:
Nadelen:
Al het werk met bestanden gebeurt via driedelige open met de instelling van codering. Alle fouten worden behandeld en gelogd, de resulterende gegevens zijn altijd correct voor de locale.
Voordelen:
Nadelen: