Perl Language
File I / O (odczyt i zapis plików)
Szukaj…
Parametry
Tryb | Wyjaśnienie |
---|---|
> | Napisz (trunc) . Zastąpi istniejące pliki. Tworzy nowy plik, jeśli nie znaleziono pliku |
>> | Napisz (dołącz) . Nie nadpisuje plików, ale dodaje na końcu nową zawartość. Utworzy również plik, jeśli zostanie użyty do otwarcia nieistniejącego pliku. |
< | Czytaj Otwiera plik w trybie tylko do odczytu. |
+< | Odczyt / zapis . Plik nie zostanie utworzony ani obcięty. |
+> | Odczyt / zapis (obcinanie) . Utworzy i obetnie plik. |
+>> | Odczyt / zapis (dołącz) . Utworzy plik, ale go nie obetnie. |
Uwagi
chomp
jest często używany podczas czytania z pliku. Domyślnie przycina znak nowej linii, chociaż jego pełna funkcjonalność odnosi się do perldocs .
Uwaga na różnicę między znakami a bajtami: Nie wszystkie kodowania - zwłaszcza UTF-8 - używają znaków 1-bajtowych. Chociaż PerlIO radzi sobie z tym bezbłędnie, istnieje jedna potencjalna pułapka:
-
read
używa znaków dla jego długości i parametrów przesunięcia -
seek
itell
zawsze używaj bajtów do pozycjonowania
Więc nie używaj arytmetyki opartej na tych mieszanych wartościach. Zamiast używać np Encode::encode('utf8',$value_by_read)
, aby uzyskać oktetów (bajtów) od read
wyniku, której liczyć można użyć z tell
i seek
.
Odczytywanie z pliku
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>);
Jeśli wiesz, że plik wejściowy to UTF-8, możesz określić kodowanie:
open my $fh, '<:encoding(utf8)', $filename or die "Failed to open file: $filename";
Po zakończeniu odczytu z pliku uchwyt pliku powinien zostać zamknięty:
close $fh or warn "close failed: $!";
Zobacz także: Odczytywanie pliku do zmiennej
Innym i szybszym sposobem na odczytanie pliku jest użycie File :: Slurper Module. Jest to przydatne, jeśli pracujesz z wieloma plikami.
use File::Slurper;
my $file = read_text("path/to/file"); # utf8 without CRLF transforms by default
print $file; #Contains the file body
Zobacz także: [Odczytywanie pliku za pomocą slurp]
Napisz do pliku
Ten kod otwiera plik do zapisu. Zwraca błąd, jeśli nie można otworzyć pliku. Zamyka również plik na końcu.
#!/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: $!";
Teraz mamy otwarty plik gotowy do zapisu, do którego uzyskujemy dostęp poprzez $fh
(ta zmienna nazywa się uchwytem pliku ). Następnie możemy skierować dane wyjściowe do tego pliku za pomocą operatora 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: $!";
Operator open
ma zmienną skalarną (w tym przypadku $fh
) jako swój pierwszy parametr. Ponieważ jest zdefiniowany w open
operatorze, jest traktowany jako uchwyt pliku . Drugi parametr ">"
(większy niż) określa, że plik jest otwierany do zapisu. Ostatni parametr to ścieżka do pliku, w którym mają zostać zapisane dane.
Aby zapisać dane do pliku, używany jest operator print
wraz z uchwytem pliku . Zauważ, że w operatorze print
nie ma przecinka między uchwytem pliku a samą instrukcją, wystarczy spacja.
Otwieranie uchwytu pliku do odczytu
Otwieranie ogólnych plików tekstowych ASCII
open my $filehandle, '<', $name_of_file or die "Can't open $name_of_file, $!";
Jest to podstawowy idiom dla „domyślnego” we / wy pliku i sprawia, że $filehandle
pliku $filehandle
jest czytelnym strumieniem wejściowym bytes
, filtrowanym przez domyślny dekoder specyficzny dla systemu, który można ustawić lokalnie za pomocą open
pragmy
Sam Perl nie obsługuje błędów w otwieraniu plików, więc musisz sobie z nimi poradzić, sprawdzając warunek wyjścia open
. $!
jest zapełniany komunikatem o błędzie, który spowodował błąd otwarcia.
W systemie Windows domyślnym dekoderem jest filtr „CRLF”, który mapuje dowolne sekwencje „\ r \ n” na wejściu na „\ n”
Otwieranie plików binarnych
open my $filehandle, '<:raw', 'path/to/file' or die "Can't open $name_of_file, $!";
Oznacza to, że Perl nie powinien wykonywać tłumaczenia CRLF
w systemie Windows.
Otwieranie plików tekstowych UTF8
open my $filehandle, '<:raw:encoding(utf-8)', 'path/to/file'
or die "Can't open $name_of_file, $!";
To określa, że Perl powinien unikać translacji CRLF
, a następnie dekodować powstałe bajty na ciągi znaków (wewnętrznie zaimplementowane jako tablice liczb całkowitych, które mogą przekraczać 255), zamiast ciągów bajtów
Odczytywanie i zapisywanie do pliku
Przed czytaniem i pisaniem plików tekstowych powinieneś wiedzieć, jakiego kodowania użyć. Więcej informacji na temat kodowania znajduje się w dokumentacji Perla Unicode . Tutaj pokazujemy ustawienie UTF-8 jako domyślnego kodowania i dekodowania dla funkcji open
. Odbywa się to za pomocą open
pragmy u góry kodu (tuż po use strict;
i use warnings;
byłoby właściwe):
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std );
Funkcja open
tworzy uchwyt pliku używany do odczytu i / lub zapisu do pliku. Funkcja open
ma sygnaturę
open(FILEHANDLE, MODE, FILEPATH)
i zwraca fałszywą wartość, jeśli operacja się nie powiedzie. Opis błędu jest następnie zapisywany w $!
.
Czytanie
#!/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!";
Pisanie
#!/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!";
Czytanie kawałków
Otwieranie i czytanie dużych plików może zająć trochę czasu i zasobów. Jeśli wymagana jest tylko niewielka część zawartości, dobrym pomysłem może być odczytanie zawartości fragmentów za pomocą funkcji read
z podpisem
read(FILEHANDLE, SCALAR, LENGTH, OFFSET)
FILEHANDLE
musi być otwarty uchwyt pliku, SCALAR
odbędzie odczytane dane po operacji. LENGTH
określa liczbę znaków do odczytania, począwszy od OFFSET
. Funkcja zwraca liczbę odczytanych znaków, 0
jeśli osiągnięto koniec pliku i undef
w przypadku błędu.
read($file_handle, $data, 16, 0);
Odczytuje 16 znaków od początku pliku do $data
.
„użyj autodie” i nie będziesz musiał sprawdzać błędów otwierania / zamykania plików
autodie
umożliwia pracę z plikami bez konieczności jawnego sprawdzania błędów otwierania / zamykania.
Od wersji Perla 5.10.1 pragma autodie
jest dostępna w rdzeniu Perla. Gdy jest używany, Perl automatycznie sprawdza błędy podczas otwierania i zamykania plików.
Oto przykład, w którym wszystkie wiersze jednego pliku są odczytywane, a następnie zapisywane na końcu pliku dziennika.
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;
Nawiasem mówiąc, technicznie zawsze powinieneś sprawdzać print
wyciągi. Wiele osób tego nie robi, ale perl
(interpreter Perla) nie robi tego automatycznie , autodie
jak autodie
.
Przewiń uchwyt pliku
Czasami konieczne jest cofnięcie się po przeczytaniu.
# 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;
Odczytywanie i zapisywanie skompresowanych plików gzip
Pisanie spakowanego pliku
Aby napisać plik spakowany gzipem, use
modułu IO::Compress::Gzip
i utwórz uchwyt pliku, tworząc nową instancję IO::Compress::Gzip
dla żądanego pliku wyjściowego:
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;
Odczytywanie z gzipowanego pliku
Aby odczytać z pliku spakowanego gzipem, use
modułu IO::Uncompress::Gunzip
a następnie utwórz uchwyt pliku, tworząc nową instancję IO::Uncompress::Gunzip
dla pliku wejściowego:
#!/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;
Ustawienie domyślnego kodowania dla IO
# encode/decode UTF-8 for files and standard input/output
use open qw( :encoding(UTF-8) :std );
Ta pragma
zmienia domyślny tryb odczytu i zapisu tekstu (plików, standardowego wprowadzania, standardowego wyjścia i standardowego błędu) na UTF-8, co jest zwykle tym, czego chcesz, gdy piszesz nowe aplikacje.
ASCII jest podzbiorem UTF-8, więc nie powinno to powodować żadnych problemów ze starszymi plikami ASCII i pomoże chronić cię przed przypadkowym uszkodzeniem plików, które może wystąpić podczas traktowania plików UTF-8 jako ASCII.
Ważne jest jednak, aby znać kodowanie plików, z którymi mamy do czynienia, i odpowiednio je obsługiwać. ( Powody, dla których nie powinniśmy ignorować Unicode. ) Aby uzyskać bardziej szczegółowe informacje na temat Unicode, zobacz temat Perl Unicode .