Операции с каталогами

Как мы отмечали ранее, в UNIX каталоги являются файлами специального формата, помеченными в структурах своих индексных дескрипторов как каталоги (поле rdev). Блоки данных каталогов содержат множество пар — имя файла, содержащегося в каталоге, и числовое значение его индексного дескриптора.
Работа с каталогами в Perl, по существу, ничем не отличается от работы с любым другим файлом. Перед началом работы с ним его следует открыть обращением к стандартной функции opendir( ), которая создает в программе дескриптор каталога, используемый в качестве ссылки на открытый каталог при выполнении необходимых операций:
opendir ДЕСКРИПТОР, ИМЯ_КАТАЛОГА;
Отметим, что для дескрипторов каталогов в таблице символов Perl создается собственное пространство имен. Это означает, что в программе могут существовать, совершенно не конфликтуя между собой, дескрипторы файла и каталога с одинаковыми именами:
open CD, "/usr/out.dat"; # дескриптор файла 
opendir CD, "/usr";      # Дескриптор каталога
ПРИМЕЧАНИЕ Использование одинаковых имен для дескрипторов файла и каталога может запутать самого пользователя. Однако для perl такой проблемы не существует: интерпретатор всегда точно знает, какой дескриптор следует использовать.
Для чтения содержащихся в каталоге файлов используется функция readdir( ):
readdir ДЕСКРИПТОР;
Для открытого каталога в списковом контексте она возвращает список имен всех файлов каталога или пустой список, если все имена уже были прочитаны. Эта же функция в скалярном контексте возвращает следующее имя файла из открытого каталога или неопределенное значение undef, если были прочитаны все имена файлов.
Отметим, что имена подкаталогов первого уровня, содержащихся в указанном каталоге, также включаются в список файлов этого каталога. Более того, специальные имена . и .., используемые соответственно для обозначения каталога верхнего уровня для текущего каталога и самого текущего каталога, также входят в список содержащихся в каталоге файлов. Поэтому, если каталог пуст (не содержит ни одного файла), то функция чтения имен файлов каталога возвращает эти два специальных имени в списковом контексте, а в скалярном последовательно возвращает их имена.
Открытый в программе каталог закрывается функцией closedir( ) с единственным параметром — дескриптором каталога:
closedir ДЕСКРИПТОР;
Эта функция обращается к соответствующей системной команде и возвращает значение «истина» в случае успешности выполнения операции закрытия каталога и «ложь» в противном случае.
Программа из листинга 6.11 печатает содержимое каталога C:\DOS в операционной системе Windows.
Листинг 6.11. Печать содержимого каталога
#!  perl  -w
opendir FDIR, "C:\\dos"; 
while( $name = readdir FDIR) { 
  print("$name\n");
}
closedir FDIR;
Функция readdir ( ) возвращает просто имя файла соответствующего открытого каталога. Для получения полного имени файла, которое требуется во всех операциях с файлами, его следует создать в программе вручную, например добавив к имени файла полное имя открытого каталога:
"c:\\dos\\" . $name
Можно также перед операциями с файлами какого-либо каталога сделать этот каталог текущим вызовом функции chdir( ), единственным необязательным параметром которой является полное или относительное имя каталога. В случае вызова без параметров функция устанавливает текущий каталог равным значению переменной окружения НОМЕ, если она установлена, или LOGDIR в противном случае. Получить или установить значение переменной окружения можно с помощью специального хэш-массива %ENV с ключом, равным имени переменной окружения, например $ENV{HOME} или $ENV{LOGDIR}. Если ни одна из указанных переменных окружения не установлена, то функция chdir без параметров ничего не делает. Она возвращает значение «истина», если произошло успешное обращение к соответствующей системной команде и текущий каталог изменен, и «ложь» в противном случае. В листинге 6.12 эта функция используется в алгоритме печати имен всех подкаталогов открытого каталога.
Листинг 6.12. Печать имен всех подкаталогов открытого каталога
#!  perl  -w
opendir FDIR, "c:\\dos";
chdir "c:\\dos";                 # Устанавливаем текущий каталог
while( $name = readdir FDIR) {
  print("$name\n") if -d $name;  # Является файл каталогом?
}
closedir FDIR;
Иногда после чтения части содержимого каталога возникает необходимость снова вернуться к его началу. Функцией rewinddir( ) текущая позиция в каталоге устанавливается на начало, что позволяет осуществлять повторное чтение имей файлов каталога, не закрывая его. Единственным параметром этой функции является дескриптор открытого каталога.
Для создания нового каталога следует воспользоваться функцией mkdir( ), параметрами которой являются имя каталога и необязательный режим доступа (восьмеричное число):
mkdir ИМЯ_КАТАЛОГА [, РЕЖИМ];
Если задается не полное имя каталога, то он создается в текущем каталоге. В случае вызова функции с одним параметром режим доступа по умолчанию устанавливается равным 0777. Возвращаемым значением функции создания нового каталога mkdir( ) является «истина», если каталог создан, и «ложь», если произошла какая-либо ошибка, В последнем случае в специальной переменной $! хранится объяснение причины, по которой каталог не был создан.
Удалить каталог можно функцией rmdir( ) с параметром, содержащим строку с именем каталога. Если параметр не задан, то используется содержимое специальной переменной $_. Как и функция создания каталога, эта функция возвращает значение «истина» в случае успешного удаления каталога и «ложь» в противном случае, записывая в переменную $! объяснение возникшей ошибки.
ПРИМЕЧАНИЕ Функция rmdir( ) удаляет только пустой каталог. Если он содержит другие пустые каталоги, их надо удалить заранее.

Следующая страница Содержание главы


Реклама