Perl Language
File I / O (bestanden lezen en schrijven)
Zoeken…
parameters
mode | explaination |
---|---|
> | Schrijf (trunc) . Zal bestaande bestanden overschrijven. Maakt een nieuw bestand als er geen bestand is gevonden |
>> | Schrijf (toevoegen) . Zal bestanden niet overschrijven maar nieuwe inhoud toevoegen aan het einde ervan. Maakt ook een bestand als het wordt gebruikt voor het openen van een niet-bestaand bestand. |
< | Lezen . Opent het bestand in alleen-lezen modus. |
+< | Lezen / schrijven . Het bestand wordt niet gemaakt of afgekapt. |
+> | Lezen / schrijven (trunc) . Zal het bestand maken en afkappen. |
+>> | Lezen / schrijven (toevoegen) . Zal het bestand maken maar niet afkappen. |
Opmerkingen
chomp
wordt vaak gebruikt bij het lezen van een bestand. Standaard wordt het newline-teken bijgesneden , hoewel voor zijn volledige functionaliteit naar de perldocs wordt verwezen .
Pas op voor het verschil tussen tekens en bytes: niet alle coderingen - vooral UTF-8 - gebruiken 1-byte-tekens. Hoewel dit vrijwel perfect wordt afgehandeld door PerlIO, is er een potentiële valkuil:
-
read
gebruikt tekens voor de lengte- en offsetparameters -
seek
entell
altijd bytes gebruiken voor positionering
Gebruik dus geen rekenkunde op basis van deze gemengde waarden. Gebruik in plaats daarvan bv Encode::encode('utf8',$value_by_read)
aan de octetten (bytes) te krijgen van een read
resultaat, waarvan tel je kunt dan met tell
en seek
.
Uit een bestand lezen
my $filename = '/path/to/file';
open my $fh, '<', $filename or die "Failed to open file: $filename";
# You can then either read the file one line at a time...
while(chomp(my $line = <$fh>)) {
print $line . "\n";
}
# ...or read whole file into an array in one go
chomp(my @fileArray = <$fh>);
Als u weet dat uw invoerbestand UTF-8 is, kunt u de codering opgeven:
open my $fh, '<:encoding(utf8)', $filename or die "Failed to open file: $filename";
Nadat het lezen uit het bestand is voltooid, moet de bestandshandle worden gesloten:
close $fh or warn "close failed: $!";
Zie ook: Een bestand in een variabele lezen
Een andere en snellere manier om een bestand te lezen, is door File :: Slurper Module te gebruiken. Dit is handig als u met veel bestanden werkt.
use File::Slurper;
my $file = read_text("path/to/file"); # utf8 without CRLF transforms by default
print $file; #Contains the file body
Zie ook: [Een bestand lezen met slurp]
Schrijf naar een bestand
Deze code opent een bestand om te schrijven. Retourneert een fout als het bestand niet kon worden geopend. Sluit ook het bestand aan het einde.
#!/usr/bin/perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
# Open "output.txt" for writing (">") and from now on, refer to it as the variable $fh.
open(my $fh, ">", "output.txt")
# In case the action failed, print error message and quit.
or die "Can't open > output.txt: $!";
Nu hebben we een open bestand klaar om te schrijven waartoe we toegang krijgen via $fh
(deze variabele wordt een filehandle genoemd ). Vervolgens kunnen we direct uitvoer naar dat bestand met de print
operator:
# Print "Hello" to $fh ("output.txt").
print $fh "Hello";
# Don't forget to close the file once we're done!
close $fh or warn "Close failed: $!";
De open
operator heeft een scalaire variabele ( $fh
in dit geval) als eerste parameter. Omdat het is gedefinieerd in de open
operator, wordt het behandeld als een filehandle . Tweede parameter ">"
(groter dan) definieert dat het bestand wordt geopend voor schrijven. De laatste parameter is het pad van het bestand waarnaar de gegevens moeten worden geschreven.
Om de gegevens te schrijven in het bestand, de print
wordt operator gebruikt in combinatie met de filehandle. Merk op dat in de print
operator is er geen komma tussen de filehandle en de verklaring zelf, gewoon witruimte.
Een FileHandle openen om te lezen
Generieke ASCII-tekstbestanden openen
open my $filehandle, '<', $name_of_file or die "Can't open $name_of_file, $!";
Dit is het basis-idioom voor "standaard" File IO en maakt $filehandle
een leesbare invoerstroom van bytes
, gefilterd door een standaard systeemspecifieke decoder, die lokaal kan worden ingesteld met de open
pragma
Perl zelf verwerkt geen fouten bij het openen van bestanden, dus u moet deze zelf behandelen door de exit-status van open
. $!
is gevuld met het foutbericht dat ervoor zorgde dat open faalde.
In Windows is de standaarddecoder een "CRLF" -filter, die alle "\ r \ n" -reeksen in de invoer toewijst aan "\ n"
Binaire bestanden openen
open my $filehandle, '<:raw', 'path/to/file' or die "Can't open $name_of_file, $!";
Dit geeft aan dat Perl geen CRLF
vertaling op Windows mag uitvoeren.
UTF8-tekstbestanden openen
open my $filehandle, '<:raw:encoding(utf-8)', 'path/to/file'
or die "Can't open $name_of_file, $!";
Geeft aan dat Perl moet zowel voorkomen CRLF
translatie en vervolgens decoderen van de resulterende bytes in tekenreeksen (intern geïmplementeerd als arrays van integers, die meer dan 255), in plaats van strengen bytes
Lezen van en schrijven naar een bestand
Voordat u tekstbestanden leest en schrijft, moet u weten welke codering u moet gebruiken. Zie de Perl Unicode-documentatie voor meer informatie over codering . Hier tonen we de instelling van UTF-8 als standaardcodering en decodering voor de functie open
. Dit wordt gedaan door het open
pragma bovenaan uw code te gebruiken (direct na use strict;
en use warnings;
zou gepast zijn):
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std );
De open
functie maakt een filehandle die wordt gebruikt voor het lezen van en / of schrijven naar een bestand. De open
functie heeft de handtekening
open(FILEHANDLE, MODE, FILEPATH)
en retourneert een valse waarde als de bewerking mislukt. De foutbeschrijving wordt vervolgens opgeslagen in $!
.
Lezing
#!/usr/bin/perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
my $file_path = "/path/to/file";
open(my $file_handle, '<', $file_path) or die "Could not open file! $!";
while(my $row = <$file_handle>) {
print chomp($row), "\n";
}
close $file_handle
or warn "Close failed!";
Schrijven
#!/usr/bin/perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
my $file_path = "/path/to/file";
open(my $file_handle, '>', $file_path) or die "Could not open file! $!";
print $file_handle "Writing to a file";
close $file_handle
or warn "Close failed!";
Brokken lezen
Het openen en lezen van grote bestanden kan enige tijd en middelen vergen. Als slechts een klein deel van de inhoud nodig is, is het misschien een goed idee om de inhoud in stukken te lezen met behulp van de read
functie die de handtekening heeft
read(FILEHANDLE, SCALAR, LENGTH, OFFSET)
FILEHANDLE
moet een geopende bestandsingang zijn, SCALAR
FILEHANDLE
de gelezen gegevens na de bewerking. LENGTH
geeft het aantal tekens aan dat moet worden gelezen vanaf de OFFSET
. De functie retourneert het aantal gelezen tekens, 0
als het einde van het bestand is bereikt en undef
in geval van een fout.
read($file_handle, $data, 16, 0);
Leest 16 tekens vanaf het begin van het bestand in $data
.
"gebruik autodie" en u hoeft de openings- / sluitingsfouten van het bestand niet te controleren
autodie
kunt u met bestanden werken zonder expliciet te moeten controleren op open / sluit-fouten.
Sinds Perl 5.10.1 is het autodie
pragma beschikbaar in Core Perl. Bij gebruik zal Perl automatisch controleren op fouten bij het openen en sluiten van bestanden.
Hier is een voorbeeld waarin alle regels van één bestand worden gelezen en vervolgens naar het einde van een logbestand worden geschreven.
use 5.010; # 5.010 and later enable "say", which prints arguments, then a newline
use strict; # require declaring variables (avoid silent errors due to typos)
use warnings; # enable helpful syntax-related warnings
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
use autodie; # Automatically handle errors in opening and closing files
open(my $fh_in, '<', "input.txt"); # check for failure is automatic
# open a file for appending (i.e. using ">>")
open( my $fh_log, '>>', "output.log"); # check for failure is automatic
while (my $line = readline $fh_in) # also works: while (my $line = <$fh_in>)
{
# remove newline
chomp $line;
# write to log file
say $fh_log $line or die "failed to print '$line'"; # autodie doesn't check print
}
# Close the file handles (check for failure is automatic)
close $fh_in;
close $fh_log;
By the way, moet je technisch gezien altijd controleren print
statements. Veel mensen doen dat niet, maar perl
(de Perl-interpreter) doet dit niet automatisch en autodie
ook niet .
Spoel een filehandle terug
Soms is het nodig om na het lezen terug te gaan.
# identify current position in file, in case the first line isn't a comment
my $current_pos = tell;
while (my $line = readline $fh)
{
if ($line =~ /$START_OF_COMMENT_LINE/)
{
push @names, get_name_from_comment($line);
}
else {
last; # break out of the while loop
}
$current_pos = tell; # keep track of current position, in case we need to rewind the next line read
}
# Step back a line so that it can be processed later as the first data line
seek $fh, $current_pos, 0;
Gecomprimeerde bestanden lezen en schrijven
Een gzipped bestand schrijven
Om een gzipped-bestand te schrijven, use
de module IO::Compress::Gzip
en maakt u een filehandle door een nieuwe instantie van IO::Compress::Gzip
voor het gewenste uitvoerbestand:
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
use IO::Compress::Gzip;
my $fh_out = IO::Compress::Gzip->new("hello.txt.gz");
print $fh_out "Hello World!\n";
close $fh_out;
use IO::Compress::Gzip;
Lezen van een ingepakt bestand
use
de module IO::Uncompress::Gunzip
en maak vervolgens een filehandle door een nieuw exemplaar van IO::Uncompress::Gunzip
voor een invoerbestand:
#!/bin/env perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
use IO::Uncompress::Gunzip;
my $fh_in = IO::Uncompress::Gunzip->new("hello.txt.gz");
my $line = readline $fh_in;
print $line;
De standaardcodering instellen voor IO
# encode/decode UTF-8 for files and standard input/output
use open qw( :encoding(UTF-8) :std );
Dit pragma
wijzigt de standaardmodus voor het lezen en schrijven van tekst (bestanden, standaardinvoer, standaarduitvoer en standaardfout) in UTF-8, wat u doorgaans wilt bij het schrijven van nieuwe toepassingen.
ASCII is een subset van UTF-8, dus dit zal naar verwachting geen problemen met oudere ASCII-bestanden veroorzaken en u helpen de onbedoelde bestandscorruptie te voorkomen die kan optreden bij het behandelen van UTF-8-bestanden als ASCII.
Het is echter belangrijk dat u weet wat de codering van uw bestanden is waarmee u te maken hebt en deze dienovereenkomstig afhandelt. ( Redenen dat we Unicode niet moeten negeren. ) Zie het onderwerp Perl Unicode voor een uitgebreidere behandeling van Unicode.