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:
-
readużywa znaków dla jego długości i parametrów przesunięcia -
seekitellzawsze 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 .