Szukaj…


Sposób ręczny

open my $fh, '<', $filename
    or die "Could not open $filename for reading: $!";
my $contents = do { local $/; <$fh> };

Po otwarciu pliku (read man perlio jeśli chcesz przeczytać konkretne kodowanie pliku zamiast surowych bajtów), sztuką jest w do bloku: <$fh> uchwyt pliku w operatora diamentowej, zwraca pojedynczy rekord z pliku . Zmienna „separator rekordów wejściowych” $/ określa, czym jest „rekord” - domyślnie jest ustawiony na znak nowej linii, więc „rekord” oznacza „pojedynczą linię”. Ponieważ $/ jest zmienną globalną, local robi dwie rzeczy: tworzy tymczasową lokalną kopię $/ , która zniknie na końcu bloku, i nadaje jej (nie) wartość undef („wartość”, którą Perl daje do niezainicjowanych zmiennych). Gdy separator rekordów wejściowych ma tę (nie) wartość, operator diamentów zwróci cały plik. (Uważa, że cały plik jest pojedynczą linią.)

Używając do , możesz nawet obejść ręcznie otwierając plik. W celu wielokrotnego odczytu plików

sub readfile { do { local(@ARGV,$/) = $_[0]; <> } }
my $content = readfile($filename);

może być użyte. Tutaj zlokalizowana jest inna zmienna globalna ( @ARGV ), która symuluje ten sam proces, który jest używany podczas uruchamiania skryptu perl z parametrami. $/ jest wciąż undef , ponieważ tablica przed nim „zjada” wszystkie przychodzące argumenty. Następnie operator diamond <> ponownie dostarcza jeden rekord określony przez $/ (cały plik) i wraca z do blok, który z kolei powrocie z sub.

Okręt podwodny nie ma jawnej obsługi błędów, co jest złą praktyką! Jeśli podczas odczytu pliku wystąpi błąd, otrzymasz undef jako wartość zwracaną, w przeciwieństwie do pustego ciągu z pustego pliku.

Inną wadą ostatniego kodu jest fakt, że nie można używać PerlIO do różnych kodowań plików - zawsze otrzymuje się surowe bajty.

Ścieżka :: Tiny

Kilka razy użycie w skrypcie idiomu z The Manual Way staje się nużące, więc możesz wypróbować moduł.

use Path::Tiny;
my $contents = path($filename)->slurp;

Możesz przekazać opcję binmode , jeśli potrzebujesz kontroli nad kodowaniem plików, zakończeniami linii itp. - patrz man perlio :

my $contents = path($filename)->slurp( {binmode => ":encoding(UTF-8)"} );

Path::Tiny ma również wiele innych funkcji do obsługi plików, więc może to być dobry wybór.

Plik :: Slurper

Jest to minimalistyczny moduł, który tylko slurps pliki do zmiennych, nic więcej.

use File::Slurper 'read_text';
my $contents = read_text($filename);

read_text() przyjmuje dwa opcjonalne parametry w celu określenia kodowania pliku i tego, czy zakończenia linii powinny być tłumaczone między standardami unixish LF czy DOSish CRLF:

my $contents = read_text($filename, 'UTF-8', 1);

Plik :: Slurp

Nie używaj tego. Chociaż istnieje już od dłuższego czasu i wciąż jest modułem sugerowanym przez większość programistów, jest zepsuty i prawdopodobnie nie zostanie naprawiony .

Slurowanie pliku do zmiennej tablicowej

open(my $fh, '<', "/some/path") or die $!;
my @ary = <$fh>;

Podczas oceny w kontekście listy operator diamentów zwraca listę składającą się ze wszystkich linii w pliku (w tym przypadku przypisując wynik do kontekstu listy dostaw macierzy). Terminator linii zostaje zachowany i można go usunąć przez chomping:

chomp(@ary); #removes line terminators from all the array elements.

Plik Slurp w jednym wierszu

Separator rekordów wejściowych można określić za pomocą przełącznika -0 ( zero , nie duże O ). Jako wartość przyjmuje liczbę ósemkową lub szesnastkową. Każda wartość 0400 lub wyższa spowoduje, że Perl będzie slurpował pliki, ale zgodnie z konwencją wartością używaną do tego celu jest 0777 .

perl -0777 -e 'my $file = <>; print length($file)' input.txt

Idąc dalej z minimalizmem, podanie przełącznika -n powoduje, że Perl automatycznie czyta każdą linię (w naszym przypadku - cały plik) do zmiennej $_ .

perl -0777 -ne 'print length($_)' input.txt


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow