Шаг 29.
Работа с файлами. Дескрипторы файлов

    На этом шаге мы приведем общие сведения по работе с файлами.

    Когда в программе мы создаем переменные и храним в них разнообразные данные, мы теряем их по завершении работы программы. Если нам необходимо сохранить данные и использовать их в разрабатываемых программах, мы создаем файл, записываем в него данные и сохраняем его на диске. Практически любой язык программирования предоставляет программисту средства манипулирования файлами и хранимыми в них данными.

    Доступ к файлам в программе Perl осуществляется через специально создаваемые дескрипторы, которые можно рассматривать как некоторый особый вид переменных. Один дескриптор в каждый момент времени может быть связан с одним и только одним файлом, хотя на протяжении всей программы один и тот же дескриптор можно последовательно связывать с разными файлами.

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

Дескрипторы файлов

    Дескриптор - это символическое имя, которое используется в программе Perl для представления файла, устройства, сокета или программного канала. При создании дескриптора он "присоединяется" к соответствующему объекту данных и представляет его в операциях ввода/вывода. Мы дали наиболее полное определение дескриптора, чтобы читатель понимал, что дескриптор позволяет работать не только с данными файлов, но и с данными других специальных программных объектов, реализующих специфические задачи получения и передачи данных. Когда дескриптор присоединен к файлу, мы будем называть его дескриптором файла.


    Замечание. При открытии файла в системе UNIX ему также назначается файловый дескриптор, или дескриптор файла, который ничего общего не имеет с файловым дескриптором Perl. В UNIX дескриптор файла является целым числом, тогда как в Perl это символическое имя, по которому мы можем ссылаться на файл. Чтобы получить числовой файловый дескриптор в программе Perl, можно воспользоваться функцией fileno().

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

    open( LOGFILE, "> /temp/logfile.log");

    Этот оператор создает дескриптор с именем LOGFILE и присоединяет его к файлу с указанным именем, который открывается в режиме записи (строка второго параметра начинается с символа ">"). На этом шаге мы не будем касаться вопросов, связанных с режимом открытия файла, а сконцентрируем наше внимание на дескрипторах. В следующих шагах режимы открытия файла будут рассмотрены нами подробнее.

    Дескриптор, как указывалось, является символическим именем файла и представляет собой правильный идентификатор, который не может совпадать с зарезервированными словами Perl. В нашем примере создается дескриптор LOGFILE, "замещающий" в операциях ввода/вывода файл, к которому он присоединен (/temp/logfile.log). Например, известной нам функцией print() мы можем теперь записать в этот файл значение какой-либо переменной:

    print  LOGFILE  $var;

    Любой созданный дескриптор попадает в символьную таблицу имен Perl, в которой находятся также имена всех переменных и функций. Однако дескриптор не является переменной, хотя некоторые авторы и называют его файловой переменной. В имени дескриптора не содержится никакого префикса, присущего переменным Perl ($, @ или %). Поэтому его нельзя непосредственно использовать в операции присваивания и сохранить в переменной или передать в качестве параметра в функцию. Для подобных целей приходится использовать перед его именем префикс *, который дает ссылку на глобальный тип данных. Например, предыдущий оператор печати в файл, определенный дескриптором LOGFILE, можно осуществить с помощью следующих операторов, предварительно сохранив ссылку на дескриптор в переменной $logf:

    $logf = *LOGFILE; 
    print $logf $var;

    В операции print первая переменная $logf замещает дескриптор файла LOGFILE, в который выводится значение второй переменной $var.


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

    В любой программе Perl всегда существуют три предопределенные дескриптора (STDIN, STDOUT и STDERR), которые связаны со стандартными устройствами ввода/вывода и используются некоторыми функциями Perl в качестве умалчиваемых дескрипторов файлов ввода или вывода. Как мы уже знаем, дескриптор STDIN связан со стандартным устройством ввода (обычно клавиатура), STDOUT и STDERR - со стандартным устройством вывода (обычно экран монитора). Стандартное устройство ввода используется операцией <>, если в командной строке вызова сценария Perl не задан список файлов. Дескриптор STDOUT по умолчанию используется функциями print() и die, a STDERR - функцией warn. Другие функции также используют предопределенные дескрипторы файлов для вывода своей информации.

    При вызове программ в среде Unix и DOS можно перенаправлять стандартный ввод и вывод в другие файлы, задавая в командной строке их имена с префиксами > для файла вывода и < для файла ввода:

    perl program.pl <in.dat >out.dat

    При выполнении программы program.pl все исходные данные должны быть подготовлены в файле in.dat. Вывод будет сохранен в файле out.dat, а не отображаться на экране монитора.

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

    open(STDIN, "in.dat"); 
    open(STDOUT, ">out.dat"); 
    open(STDERR, ">err.dat");

    Теперь весь стандартный ввод/вывод будет осуществляться через указанные в операторах open() файлы. Обратите внимание, что при переопределении стандартных файлов вывода и ошибок перед именами файлов стоит префикс ">", указывающий на то, что файлы открываются в режиме записи.


    Замечание. Перенаправление стандартного ввода/вывода в программе можно производить только один раз. Это переназначение действует с момента перенаправления ввода/вывода и до конца программы, причем функцией open() нельзя вернуть первоначальные установки для дескрипторов STDIN, STDOUT и STDERR.

    На следующем шаге мы познакомимся с функцией open().




Предыдущий шаг Содержание Следующий шаг