Perl Language
Fil I / O (läsning och skrivning av filer)
Sök…
parametrar
Läge | Förklaring |
---|---|
> | Skriv (trunker) . Skriver över befintliga filer. Skapar en ny fil om ingen fil hittades |
>> | Skriv (bifoga) . Skriver inte över filer utan lägger till nytt innehåll i slutet av det. Skapar också en fil om den används för att öppna en icke-befintlig fil. |
< | Läs . Öppnar filen i skrivskyddad läge. |
+< | Läs / skriv . Skapar eller trunkerar inte filen. |
+> | Läs / skriv (trunker) . Skapar och avkortar filen. |
+>> | Läs / skriv (bifoga) . Skapar men inte avkortar filen. |
Anmärkningar
chomp
används ofta när du läser från en fil. Som standard trimmar den den nya linjekaraktären, även om den för sin fulla funktionalitet hänvisar till perldokorna .
Se upp för skillnaden mellan tecken och byte: Inte alla kodningar - särskilt UTF-8 - använder 1-byte-tecken. Medan detta hanteras ganska mycket felfritt av PerlIO, finns det en potentiell fallgrop:
-
read
använder tecken för dess längd och offsetparametrar -
seek
ochtell
alltid använda byte för positionering
Så använd inte aritmetik baserat på dessa blandade värden. Encode::encode('utf8',$value_by_read)
istället t.ex. Encode::encode('utf8',$value_by_read)
att få oktetterna (bytes) från ett read
, vars räkning du sedan kan använda med tell
and seek
.
Läser från en fil
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>);
Om du vet att din inmatningsfil är UTF-8 kan du ange kodningen:
open my $fh, '<:encoding(utf8)', $filename or die "Failed to open file: $filename";
Efter avslutad läsning från filen bör filhandtaget stängas:
close $fh or warn "close failed: $!";
Se även: Läsa en fil i en variabel
Ett annat och snabbare sätt att läsa en fil är att använda File :: Slurper Module. Detta är användbart om du arbetar med många filer.
use File::Slurper;
my $file = read_text("path/to/file"); # utf8 without CRLF transforms by default
print $file; #Contains the file body
Se också: [Läsa en fil med slurp]
Skriv till en fil
Den här koden öppnar en fil för skrivning. Returnerar ett fel om filen inte kunde öppnas. Stänger också filen i slutet.
#!/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 har vi en öppen fil som är klar att skriva som vi får tillgång till via $fh
(denna variabel kallas en filhandtag ). Därefter kan vi rikta utdata till den filen med print
:
# 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: $!";
Den open
operatören har en skalvariabel ( $fh
i detta fall) som sin första parameter. Eftersom det definieras i den open
operatören behandlas det som en filhandtag . Den andra parametern ">"
(större än) definierar att filen öppnas för skrivning. Den sista parametern är sökvägen för filen att skriva data till.
För att skriva data till filen, print
är operatör används tillsammans med filehandle. Lägg märke till att det i print
finns några komma mellan filhandtaget och själva uttalandet, bara mellanrum.
Öppna en FileHandle för läsning
Öppna generiska ASCII-textfiler
open my $filehandle, '<', $name_of_file or die "Can't open $name_of_file, $!";
Detta är det grundläggande formspråket för "standard" File IO och gör $filehandle
en läsbar inmatningsström av bytes
, filtrerad av en standardsystemspecifik avkodare, som kan ställas in lokalt med det open
pragmet
Perl själv hanterar inte fel i filöppningen, så du måste hantera dem själv genom att kontrollera open
för open
. $!
fylls med felmeddelandet som orsakade att öppet misslyckades.
I Windows är standardavkodaren ett "CRLF" -filter som kartlägger alla "\ r \ n" sekvenser i ingången till "\ n"
Öppna binära filer
open my $filehandle, '<:raw', 'path/to/file' or die "Can't open $name_of_file, $!";
Detta anger att Perl inte bör utföra en CRLF
översättningen på Windows.
Öppna UTF8-textfiler
open my $filehandle, '<:raw:encoding(utf-8)', 'path/to/file'
or die "Can't open $name_of_file, $!";
Detta anger att Perl båda ska undvika CRLF
översättning och sedan avkoda de resulterande byteerna till strängar av tecken (internt implementerade som matriser av heltal som kan överstiga 255), i stället för strängar av byte
Läser från och skriver till en fil
Innan du läser och skriver textfiler bör du veta vilken kodning du ska använda. Se Perl Unicode-dokumentationen för mer information om kodning . Här visar vi inställningen av UTF-8 som standardkodning och avkodning för den open
funktionen. Detta görs genom att använda det open
pragmet nära toppen av koden (direkt efter use strict;
och use warnings;
skulle vara lämpligt):
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std );
Den open
funktionen skapar en filhandtag som används för att läsa från och / eller skriva till en fil. Den open
funktionen har signaturen
open(FILEHANDLE, MODE, FILEPATH)
och returnerar ett falskt värde om operationen misslyckas. Felsbeskrivningen lagras sedan på $!
.
Läsning
#!/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!";
Skrivning
#!/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!";
Läser bitar
Det kan ta lite tid och resurser att öppna och läsa stora filer. Om bara en liten del av innehållet krävs, kan det vara en god idé att läsa innehållet i bitar med hjälp av read
funktion som har signaturen
read(FILEHANDLE, SCALAR, LENGTH, OFFSET)
FILEHANDLE
måste vara ett öppnat filhandtag, SCALAR
kommer att hålla lästa data efter operationen. LENGTH
anger antalet tecken som ska läsas från OFFSET
. Funktionen returnerar antalet lästa tecken, 0
om slutet på filen nåddes och undef
i händelse av ett fel.
read($file_handle, $data, 16, 0);
Läser 16 tecken från filens början till $data
.
"använda autodie" och du behöver inte kontrollera filens öppna / stängda fel
autodie
låter dig arbeta med filer utan att behöva explicit kontrollera för öppna / stängda fel.
Sedan Perl 5.10.1 har autodie
pragma varit tillgängligt i Perl-kärnan. När den används används Perl automatiskt efter fel vid öppning och stängning av filer.
Här är ett exempel där alla raderna i en fil läses och skrivs till slutet av en loggfil.
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;
Förresten, du bör tekniskt alltid kontrollera print
uttalanden. Många gör det inte, men perl
(Perl-tolkaren) gör inte detta automatiskt och inte heller autodie
.
Spola tillbaka en filhandtag
Ibland är det nödvändigt att backtracka efter att ha läst.
# 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;
Läsa och skriva gzip-komprimerade filer
Skriva en gzippad fil
För att skriva en gzipped-fil use
modulen IO::Compress::Gzip
och skapar en filhandtag genom att skapa en ny instans av IO::Compress::Gzip
för önskad utdatafil:
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;
Läser från en gzippad fil
För att läsa från en gzipped-fil use
modulen IO::Uncompress::Gunzip
och skapar sedan en filhandtag genom att skapa en ny instans av IO::Uncompress::Gunzip
för inmatningsfilen:
#!/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;
Ställer in standardkodning för IO
# encode/decode UTF-8 for files and standard input/output
use open qw( :encoding(UTF-8) :std );
Detta pragma
ändrar standardläget för att läsa och skriva text (filer, standardinmatning, standardutgång och standardfel) till UTF-8, vilket vanligtvis är vad du vill ha när du skriver nya applikationer.
ASCII är en delmängd av UTF-8, så detta förväntas inte orsaka problem med äldre ASCII-filer och kommer att hjälpa dig att skydda oavsiktlig filskada som kan hända när du behandlar UTF-8-filer som ASCII.
Det är emellertid viktigt att du vet vad kodningen av dina filer är att du hanterar och hanterar dem i enlighet därmed. ( Anledningar till att vi inte borde ignorera Unicode. ) För mer djupgående behandling av Unicode, se ämnet Perl Unicode .