Perl Language
File I / O (lettura e scrittura di file)
Ricerca…
Parametri
Modalità | spiegazione |
---|---|
> | Scrivi (trunc) . Sovrascriverà i file esistenti. Crea un nuovo file se non è stato trovato alcun file |
>> | Scrivi (accoda) . Non sovrascriverà i file ma aggiungerà nuovi contenuti alla fine. Creerà anche un file se usato per aprire un file non esistente. |
< | Leggi Apre il file in modalità di sola lettura. |
+< | Leggi / scrivi . Non creerà o troncerà il file. |
+> | Leggi / scrivi (trunc) . Creerà e troncerà il file. |
+>> | Leggi / scrivi (accoda) . Creerà ma non troncerà il file. |
Osservazioni
chomp
viene spesso utilizzato durante la lettura da un file. Di default taglia il carattere di nuova riga, sebbene per la sua piena funzionalità faccia riferimento ai perldoc .
Fai attenzione alla differenza tra caratteri e byte: non tutte le codifiche, in particolare UTF-8, utilizzano caratteri a 1 byte. Sebbene questo sia gestito in modo quasi impeccabile da PerlIO, c'è una potenziale trappola di nota:
-
read
utilizza i caratteri per la lunghezza e i parametri di offset -
seek
etell
usa sempre i byte per il posizionamento
Quindi non usare aritmetica in base a questi valori misti. Usa, ad esempio, Encode::encode('utf8',$value_by_read)
per ottenere gli ottetti (byte) da un risultato di read
, il cui conteggio può quindi essere utilizzato con tell
and seek
.
Lettura da un file
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>);
Se sai che il tuo file di input è UTF-8, puoi specificare la codifica:
open my $fh, '<:encoding(utf8)', $filename or die "Failed to open file: $filename";
Dopo aver terminato la lettura dal file, il filehandle deve essere chiuso:
close $fh or warn "close failed: $!";
Vedi anche: Lettura di un file in una variabile
Un altro e più veloce modo di leggere un file è utilizzare File :: Modulo Slurper. Questo è utile se lavori con molti file.
use File::Slurper;
my $file = read_text("path/to/file"); # utf8 without CRLF transforms by default
print $file; #Contains the file body
Vedi anche: [Leggere un file con lo slurp]
Scrivi su un file
Questo codice apre un file per la scrittura. Restituisce un errore se il file non può essere aperto. Inoltre chiude il file alla fine.
#!/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: $!";
Ora abbiamo un file aperto pronto per la scrittura a cui accediamo tramite $fh
(questa variabile è chiamata filehandle ). Successivamente possiamo indirizzare l'output a quel file usando l'operatore di 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: $!";
L'operatore open
ha una variabile scalare ( $fh
in questo caso) come primo parametro. Poiché è definito nell'operatore open
, viene trattato come un filehandle . Il secondo parametro ">"
(maggiore di) definisce che il file è aperto per la scrittura. L'ultimo parametro è il percorso del file in cui scrivere i dati.
Per scrivere i dati nel file, l'operatore di print
viene utilizzato insieme al filehandle . Si noti che nell'operatore di print
non esiste una virgola tra il filehandle e l'istruzione stessa, solo spazi bianchi.
Aprire un FileHandle per la lettura
Apertura di file di testo ASCII generici
open my $filehandle, '<', $name_of_file or die "Can't open $name_of_file, $!";
Questo è l'idioma di base per il file IO "predefinito" e rende $filehandle
un flusso di input leggibile di bytes
, filtrato da un decodificatore specifico del sistema predefinito, che può essere impostato localmente con il pragma open
Lo stesso Perl non gestisce gli errori nell'apertura dei file, quindi devi gestirli da solo controllando la condizione di uscita di open
. $!
viene popolato con il messaggio di errore che ha causato l'apertura non riuscita.
Su Windows, il decodificatore predefinito è un filtro "CRLF", che mappa qualsiasi sequenza "\ r \ n" nell'input su "\ n"
Apertura di file binari
open my $filehandle, '<:raw', 'path/to/file' or die "Can't open $name_of_file, $!";
Questo specifica che Perl non dovrebbe eseguire una traduzione CRLF
su Windows.
Apertura di file di testo UTF8
open my $filehandle, '<:raw:encoding(utf-8)', 'path/to/file'
or die "Can't open $name_of_file, $!";
Questo specifica che Perl dovrebbe sia evitare la conversione CRLF
, e quindi decodificare i byte risultanti in stringhe di caratteri (implementate internamente come matrici di interi che possono superare 255), invece di stringhe di byte
Leggere e scrivere su un file
Prima di leggere e scrivere file di testo devi sapere quale codifica usare. Vedi la documentazione Unicode Perl per maggiori dettagli sulla codifica . Qui mostriamo l'impostazione di UTF-8 come codifica e decodifica predefinite per la funzione open
. Questo viene fatto usando il pragma open
vicino all'inizio del tuo codice (subito dopo l' use strict;
e use warnings;
sarebbe appropriato):
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std );
La funzione open
crea un filehandle che viene utilizzato per leggere e / o scrivere su un file. La funzione open
ha la firma
open(FILEHANDLE, MODE, FILEPATH)
e restituisce un valore falso se l'operazione fallisce. La descrizione dell'errore viene quindi memorizzata in $!
.
Lettura
#!/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!";
scrittura
#!/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!";
Pezzi di lettura
L'apertura e la lettura di file di grandi dimensioni può richiedere tempo e risorse. Se è richiesta solo una piccola parte del contenuto, potrebbe essere una buona idea leggere il contenuto in blocchi usando la funzione di read
che ha la firma
read(FILEHANDLE, SCALAR, LENGTH, OFFSET)
FILEHANDLE
deve essere un handle di file aperto, SCALAR
manterrà i dati letti dopo l'operazione. LENGTH
specifica il numero di caratteri da leggere a partire da OFFSET
. La funzione restituisce il numero di caratteri letti, 0
se la fine del file è stata raggiunta e undef
in caso di errore.
read($file_handle, $data, 16, 0);
Legge 16 caratteri dall'inizio del file in $data
.
"usa autodie" e non avrai bisogno di controllare gli errori di apertura / chiusura dei file
autodie
ti consente di lavorare con i file senza dover controllare esplicitamente gli errori di apertura / chiusura.
Da Perl 5.10.1, il autodie
è disponibile nel core Perl. Se usato, Perl controllerà automaticamente gli errori durante l'apertura e la chiusura dei file.
Ecco un esempio in cui tutte le righe di un file vengono lette e quindi scritte alla fine di un file di registro.
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;
A proposito, dovresti controllare tecnicamente sempre print
dichiarazioni di print
. Molte persone non lo fanno, ma perl
(l'interprete Perl) non lo fa automaticamente e nemmeno l' autodie
.
Riavvolgi un filehandle
A volte è necessario tornare indietro dopo aver letto.
# 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;
Lettura e scrittura di file compressi gzip
Scrivere un file gzip
Per scrivere un file gzip, use
il modulo IO::Compress::Gzip
e crea un filehandle creando una nuova istanza di IO::Compress::Gzip
per il file di output desiderato:
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;
Lettura da un file gzip
Per leggere da un file gzip, use
il modulo IO::Uncompress::Gunzip
e quindi creare un filehandle creando una nuova istanza di IO::Uncompress::Gunzip
per il file di input:
#!/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;
Impostazione della codifica predefinita per IO
# encode/decode UTF-8 for files and standard input/output
use open qw( :encoding(UTF-8) :std );
Questo pragma
cambia la modalità predefinita di lettura e scrittura del testo (file, input standard, output standard e errore standard) in UTF-8, che è in genere ciò che si desidera quando si scrivono nuove applicazioni.
ASCII è un sottoinsieme di UTF-8, quindi non ci si aspetta che questo causi problemi con i file ASCII legacy e ti aiuterà a proteggerti dal danneggiamento accidentale dei file che può accadere quando si trattano file UTF-8 come ASCII.
Tuttavia, è importante sapere quale è la codifica dei file che si sta trattando e gestirli di conseguenza. ( Motivi per cui non dovremmo ignorare Unicode. ) Per un trattamento più approfondito di Unicode, consultare l' argomento Perl Unicode .