Jak odczytać plik tekstowy w Perl

Zadanie. Jest plik tekstowy. Chcesz pobrać jego zawartość w скалярную zmiennej w Perlu programu.

Taki problem pojawia się dość często. Na przykład takie zadanie może wystąpić do odczytu plików konfiguracyjnych lub małych plików z danymi. W przypadku, gdy trzeba obsłużyć duży plik, to lepiej nie używać w ten sposób, jak używać streaming odczyt z pliku.

Rozwiązanie. Korzystać z biblioteki Path::Tiny

Najbardziej proste i wygodne rozwiązanie — to korzystać z biblioteki Perl Path::Tiny

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);

use Path::Tiny;

my $file_name = 'a.txt';

my $content = path($file_name)->slurp_utf8();

print $content;

Tu path('a.txt') tworzy obiekt klasy Path::Tiny, a ->slurp_utf8() wywołuje metodę slurp_utf8 u tego obiektu. Wynik w zmiennej $content pojawia się cała zawartość pliku.

Jest to dobre rozwiązanie, ale jest haczyk. Biblioteka Path::Tiny nie idzie w parze z Perl, trzeba ją umieścić oddzielnie. Jest to zazwyczaj nie powoduje problemów, ale w niektórych sytuacjach takie rozwiązanie nie pasuje.

Rozwiązanie. Przeczytać plik standardowymi środkami Perl

To rozwiązanie nie jest takie wygodne jak korzystanie z biblioteki Path::Tiny, trzeba więcej pisać, ale ono nie wymaga instalacji dodatkowych bibliotek.

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);

my $file_name = 'a.txt';

my $content = '';

open FILE, '<', $file_name or die $!;

while (<FILE>) {
    $content .= $_;
}

print $content;

Z pomocą open stworzyliśmy file handler FILE. Podczas pracy z open ważne jest, aby używać trzy argumenty i bardzo ważne jest, aby napisać or die, a nie || die. Dalej z pomocą while (<FILE>) biegniemy na całym plik ścieg za ściegiem i zbieramy całą zawartość do zmiennej $content.

Początkowo my przypiszemy zmiennej $content pusty wiersz ''. Jest to potrzebne do tego aby kod działał poprawnie w przypadku pustych plików (jeśli nie przypisać pusty ciąg, to w przypadku pustego pliku w zmiennej $content będzie undef).

Niebezpieczne rozwiązanie. Używać cat

Oto jeszcze jeden sposób, jak można przeczytać zawartość pliku do zmiennej. To rozwiązanie nie wymaga dodatkowych bibliotek i nie wymaga pisania wielu linii kodu, ale to костыльное rozwiązanie. Najlepiej w ogóle nie pisać. Jedyne kiedy tak można zrobić — to jest, gdy w projekcie nie Path::Tany, idzie aktywna praca i do sprawdzenia innych części programu trzeba szybko uzyskać kod, który odczytuje plik. Ale w tym przypadku trzeba się obok komentarz # TODO i przy pierwszej okazji usunąć ten kod.

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);

my $file_name = 'a.txt';

my $content = `cat $file_name`;

print $content;

Dlaczego jest to złe rozwiązanie. Po pierwsze tu nie ma obsługi błędów. Jeśli pliku nie ma, to na STDERR, zostanie wyświetlone ostrzeżenie cat: asdf: No such file or directory, ale program będzie dalej. Po drugie to nie zadziała, jeśli w nazwie pliku jest spacja. Po trzecie jeśli zawartość zmiennej $file_name otrzymujemy z zewnątrz to jest szansa, że tam będzie coś takiego jak a.txt; rm -rf / i oprócz czytania pliku zostaną jeszcze wykonane są niebezpieczne działania.

Inne artykuły