Perl Language
Чтение содержимого файла в переменную
Поиск…
Ручной способ
open my $fh, '<', $filename
or die "Could not open $filename for reading: $!";
my $contents = do { local $/; <$fh> };
После открытия файла (прочитайте man perlio
если вы хотите читать определенные кодировки файлов вместо необработанных байтов), трюк находится в блоке do
: <$fh>
, дескриптор файла в алмазном операторе, возвращает одну запись из файла , Переменная «input record separator» $/
указывает, что такое «запись» - по умолчанию она установлена на символ новой строки, поэтому «запись» означает «одна строка». Поскольку $/
- глобальная переменная, local
выполняет две вещи: создает временную локальную копию $/
которая будет исчезать в конце блока, и дает ему (не) значение undef
(значение, которое Perl дает к неинициализированным переменным). Когда разделитель входных данных имеет это (не) значение, оператор алмаза вернет весь файл. (Он рассматривает весь файл как одну строку.)
Используя do
, вы можете даже вручную открыть файл. Для повторного чтения файлов,
sub readfile { do { local(@ARGV,$/) = $_[0]; <> } }
my $content = readfile($filename);
может быть использован. Здесь другая глобальная переменная ( @ARGV
) локализована для моделирования того же процесса, который используется при запуске скрипта perl с параметрами. $/
все еще undef
, так как массив перед ним «ест» все входящие аргументы. Затем оператор алмаза <>
снова поставляет одну запись, определяемую $/
(весь файл), и возвращает из блока do
, которые, в свою очередь, возвращаются из суб.
Sub не имеет явной обработки ошибок, что является плохой практикой! Если во время чтения файла возникает ошибка, вы получите undef
как возвращаемое значение, а не пустую строку из пустого файла.
Другим недостатком последнего кода является тот факт, что вы не можете использовать PerlIO для разных кодировок файлов - вы всегда получаете необработанные байты.
Путь :: Крошечный
Использование идиомы из Manual Way несколько раз в сценарии скоро становится утомительным, поэтому вы можете попробовать модуль.
use Path::Tiny;
my $contents = path($filename)->slurp;
Вы можете передать опцию binmode
если вам нужно контролировать кодировки файлов, окончания строк и т. Д. - см. man perlio
:
my $contents = path($filename)->slurp( {binmode => ":encoding(UTF-8)"} );
Path::Tiny
также имеет множество других функций для работы с файлами, поэтому он может быть хорошим выбором.
Файл :: Slurper
Это минималистский модуль, который только вставляет файлы в переменные, и ничего больше.
use File::Slurper 'read_text';
my $contents = read_text($filename);
read_text()
принимает два необязательных параметра для указания кодировки файла и должны ли переводы строк быть переведены между стандартами UNIX Unixish или DOSish CRLF:
my $contents = read_text($filename, 'UTF-8', 1);
Файл :: Slurp
Не используйте его. Хотя он существует уже давно и по-прежнему является модулем, который, по мнению большинства программистов, будет нарушен и вряд ли будет исправлен .
Разбиение файла на переменную массива
open(my $fh, '<', "/some/path") or die $!;
my @ary = <$fh>;
При оценке в контексте списка оператор алмаза возвращает список, состоящий из всех строк в файле (в этом случае присваивание результата контексту списка источников массива). Терминатор линии сохраняется и может быть удален путем прерывания:
chomp(@ary); #removes line terminators from all the array elements.
Файл Slurp в одном слое
Разделитель входных данных может быть задан с помощью ключа -0
( ноль , а не капитала O ). В качестве значения берется восьмеричное или шестнадцатеричное число. Любое значение 0400
или выше приведет к тому, что Perl будет клонировать файлы, но, по договоренности, значение, используемое для этой цели, составляет 0777
.
perl -0777 -e 'my $file = <>; print length($file)' input.txt
Идя далее с минимализмом, указание -n
switch заставляет Perl автоматически читать каждую строку (в нашем случае - весь файл) в переменную $_
.
perl -0777 -ne 'print length($_)' input.txt