Доступ к файлам
Для полноты описания работы с функцией open () следует сказать, что если имя файла представляет строку "-", то открываемый файл соответствует стандартному вводу STDIN. Это означает, что ввод с помощью созданного дескриптора файла осуществляется со стандартного устройства ввода. Если имя файла задано в виде строки ">-", то это соответствует выводу на стандартное устройство вывода, представленное в программе дескриптором STDOUT.
Замечание
Если стандартный ввод или вывод были перенаправлены, то ввод/вывод с помощью дескрипторов, соответствующих файлам "-" и ">-", будет осуществляться в файл, определенный в операции перенаправления стандартного ввода или вывода.
Последнее, что нам хотелось бы осветить в связи с дескрипторами файлов, – это создание дескриптора-дубликата. Если в строке имени файла после префикса режима открытия следует амперсанд "&", то ее оставшаяся часть рассматривается как имя дескриптора файла, а не как имя открываемого файла. В этом случае создается независимая копия этого дескриптора с именем, заданным первым параметром функции open (). Оба дескриптора имеют общий указатель текущей позиции файла, но разные буферы ввода/вывода. Закрытие одного из дескрипторов не влияет на работу другого. В программах Perl возможность создания копии дескриптора в основном применяется для восстановления стандартных файлов ввода/вывода после их перенаправления на другие файлы (пример 7.3).
#! peri – w # Создание копии дескриптора STDOUT open(OLDOUT, ">&STDOUT"); # Перенаправление стандартного вывода open(STDOUT, "> file.out") or die "Невозможно перенаправить STDOUT: $!"; # Печать в файл file.out print "Информация в перенаправленный STDOUTXn"; # Закрытие перенаправленного дескриптора стандартного вывода close(STDOUT) or die "Невозможно закрыть STDOUT: $!"; # Восстановить файл стандартного вывода open(STDOUT, ">&OLDOUT") or die "Невозможно восстановить STDOUT: $!"; # Закрыть копию дескриптора стандартного вывода STDOUT close(OLDOUT) or die "Невозможно закрыть OLDOUT: $!"; # Печать в восстановленный файл стандартного вывода print "Информация в восстановленный STDOUTXn";
Замечание
В программах следует избегать работу с одним файлом через несколько дескрипторов-копий.
По завершении работы с файлом он закрывается функцией close (). Единственным необязательным параметром этой функции является дескриптор, ассоциированный с файлом:
close ДЕСКРИПТОР;
Эта функция возвращает значение Истина, если успешно очищен буфер ввода/вывода и закрыт системный дескриптор файла. Вызванная без параметра, функция close закрывает файл, связанный с текущим дескриптором, установленным функцией select ().
Следует отметить, что закрывать файлы в программе функцией close () не обязательно. Дело в том, что открытие нового файла с дескриптором, уже связанным с каким-либо файлом, закрывает этот старый файл. Более того, при завершении программы все открытые в ней файлы закрываются. Однако такое неявное закрытие файлов таит в себе потенциальные ошибки из-за невозможности определить, завершилась ли эта операция корректно. Может оказаться, что при записи в файл переполнится диск, или будет разорвана связь с удаленным устройством вывода. Подобные ошибки можно "отловить", если использовать явное закрытие файла и проверять содержимое специальной переменной $!:
closet FILEIO) or die "Ошибка закрытия файла: $!";
Существует еще один нюанс, связанный с явным закрытием файлов. При чтении из файла специальная переменная $. (если ее значение не изменено явным образом в программе) хранит номер последней прочитанной записи файла. При явном закрытии файла функцией close () значение этой переменной обнуляется, тогда как при неявном закрытии оно остается равным номеру последней прочитанной записи старого файла и продолжает увеличиваться при операциях чтения из нового файла.