Язык программирования Perl

Потоки ввода-вывода


Система ввода-вывода Perl основана на принципах, заложенных в системе Unix и распространившихся на все современные операционные системы. Одним из основных понятий работы в программе с внешними данными являются потоки ввода-вывода. В программе обращение к потоку ввода-вывода производится через файловый манипулятор (file handle), иногда неправильно называемый дескриптором файла. При запуске любой программы автоматически открывается три потока: стандартный ввод (stdin), стандартный вывод (stdout) и стандартный протокол (stderr). Поток стандартного ввода в диалоговой операционной среде связывается с клавиатурной, а потоки стандартного вывода и стандартного протокола - с дисплейной частью консоли операционной системы. Со стандартными потоками в Perl связываются три предопределенных файловых манипулятора: соответственно STDIN, STDOUT и STDERR. Связывание имени файла с пользовательским файловым манипулятором в программе выполняется с помощью операции open(), открывающей поток обмена данными с указанным файлом. Требования надежности рекомендуют обязательно проверять все операции ввода-вывода на успешное завершение. Поэтому в случае возникновения ошибки при открытии файла программа обычно аварийно завершается с помощью функции die(), которая может выводить диагностическое сообщение в стандартный поток протокола. Например, так открывается файл и создается файловый манипулятор FILE_HANDLE:

# открыть для чтения файл по имени, взятом из $file_name open(FILE_HANDLE, $file_name) # или аварийно завершить программу с выдачей сообщения or die("Ошибка открытия файла $file_name: $!\n"); #

В случае успешного открытия файла функция open() помещает в свой первый аргумент готовый к использованию файловый манипулятор. Имя файлового манипулятора записывается без разыменовывающего префикса и по традиции выделяется заглавными буквами. Рекомендуется при открытии файла сохранять файловый манипулятор в скалярной переменной, что позволяет локализовать файловый манипулятор для использования только в текущем блоке или подпрограмме. Кроме того, скалярную переменную с файловым манипулятором можно удобно передавать в подпрограммы для выполнения в них операций ввода-вывода. Итак, вот предпочтительный способ открытия файла:


open my $file_handle, $file_name or die "Ошибка открытия файла $file_name: $!\n";

(Как и при вызове других функций в Perl, если не возникает неоднозначности, программист решает, заключать аргументы функций в круглые скобки или нет. Среди пишущих на Perl широко распространен стиль программирования без использования круглых скобок.)

При открытии файла функции, помимо файлового манипулятора и имени файла в файловой системе (абсолютного или относительного), указывается режим открытия файла. Он обозначается такими же символами, как переназначение потоков ввода-вывода в командном интерпретаторе операционной системы. Основные режимы открытия потоков ввода-вывода приведены в таблице 9.1.

Таблица 9.1. Основные режимы открытия потоков ввода-выводаОбозначениеРежим открытияПример использования
<Чтение (существующего файла с начала)open($fh, '</temp/buffer.txt')
>Перезапись (с начала файла)open($fh, '>/temp/buffer.txt')
>>Дозапись (в конец файла)open($fh, '>>/temp/buffer.txt')
+<Чтение и запись (файл должен существовать)open($fh, '+</temp/buffer.txt')
+>Запись и чтение (файл усекается)open($fh, '+>/temp/buffer.txt')
+>>Дозапись и чтениеopen($fh, '+>>/temp/buffer.txt')
Применяются две формы записи функции open(): старая с двумя аргументами, когда режим открытия указывается перед именем файла, и новая - с тремя аргументами, в которой режим открытия указывается отдельно вторым параметром. Сравните:

open $fh, '</temp/buffer.txt'; open $fh, '<', '/temp/buffer.txt';

Программисты, знающие язык C, могут воспользоваться для открытия потоков функцией sysopen(), которая аналогична функции открытия потоков в C, и к тому же позволяет более тонко настраивать режимы открытия файлов. А вообще в комплекте с Perl идет целый учебник по функции open(), который можно прочитать утилитой чтения документации:

perldoc perlopentut

Связь файлового манипулятора в программе с обрабатываемым файлом разрывается функцией закрытия потока close(), закрывающей поток ввода-вывода. Ей передается файловый манипулятор открытого файла:

close(FILE) or die("Ошибка при закрытии файла: $!\n"); close $handle or die "Ошибка закрытия файла: $!\n";

В новой многоуровневой подсистеме ввода-вывода Perl предусматривает при открытии потока вместе с режимом открытия указывать кодировку читаемых и записываемых данных, что позволяет автоматически преобразовывать информацию из одной кодировки в другую, например, так:

open my $in, "<:encoding(UTF-8)", 'utf8.txt' or die; open my $out, ">:encoding(cp1251)", 'cp1251 .txt' or die; while(<$in>){ print $out $_; } close $in or die; close $out or die;

В некоторых операционных системах (например, в MS-DOS), после открытия файла, но перед чтением двоичных данных требуется установить для файлового манипулятора режим работы с двоичными данными с помощью функции binmode($file_handle). При работе в операционных системах, не требующих установки этого режима, вызов функции binmode() не оказывает никакого действия.


Содержание раздела