Как прочитать текстовый файл в Perl

Задача. Есть текстовый файл. Нужно загрузить его содержимое в скалярную переменную в Perl программе.

Такая задача появляется достаточно часто. Например, такая задача может возникнуть для чтения конфигурационных файлов или небольших файлов с данными. В том случае если нужно обработать большой файл, то лучше не использовать этот способ, а использовать потоковое чтение из файла.

Решение. Использовать библиотеку Path::Tiny

Самое простое и удобное решение — это использовать 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;

Тут path('a.txt') создает объект класса Path::Tiny, а ->slurp_utf8() вызывает метод slurp_utf8 у этого объекта. Результат — в переменной $content появляется все содержимое файла.

Это хорошее решение, но есть одна тонкость. Библиотека Path::Tiny не идет вместе с Perl, ее нужно ставить отдельно. Обычно это не вызывает проблем, но в некоторых ситуациях такое решение не подходит.

Решение. Прочитать файл стандартными средствами Perl

Это решение не такое удобное как использование библиотеки Path::Tiny, приходится больше писать, зато оно не требует установки дополнительных библиотек.

#!/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;

С помощью open мы создали файловый хендлер FILE. При работе с open важно использовать три аргумента и очень важно написать or die, а не || die. Дальше с помощью while (<FILE>) мы бежим по всему файлу строчка за строчкой и собираем все содержимое в переменную $content.

Изначально мы присвоили переменной $content пустую строку ''. Это нужно для того чтобы код правильно работал в случае пустых файлов (если не присвоить пустую строку, то в случае пустого файла в переменной $content будет undef).

Опасное решение. Использовать cat

Вот еще один способ как можно прочитать содержимое файла в переменную. Это решение не требует дополнительных библиотек и не требует написания многих строк кода, но это костыльное решение. Лучше всего так никогда не писать. Единственное когда так можно делать — это когда в проекте нет Path::Tany, идет активная работа и для проверки других частей программы нужно быстро получить код который читает файл. Но в этом случае нужно рядом оставить комментарий # TODO и при первой возможности убрать этот код.

#!/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;

Почему это плохое решение. Во-первых тут нет обработки ошибок. Если файла нет, то на STDERR будет выведено предупреждение cat: asdf: No such file or directory, но программа будут идти дальше. Во-вторых это не сработает если в названии файла есть пробел. В-третьих если содержимое переменной $file_name мы получаем извне то есть шанс что там будет что-то вроде a.txt; rm -rf / и кроме чтения файла будут еще выполнены небезопасные действия.

Другие статьи

Комментарии