Анимация
JavaScript
|
Главная Библионтека Получение листинга каталога Прежде чем выполнять операции с каталогом, необходимо создать его дескриптор. Дескриптор каталога напоминает дескриптор файла с тем лишь отличием, что при чтении считывается не файл, а содержимое каталога. Для открытия дескриптора каталога используется функция opendir: opendir иня дескрвптора, имя каталога; В этом синтаксисе вместо следует указать дескриптор каталога, который вы хотите открыть, а вместо инеш каталога - путь к каталогу, содержимое которого нужно прочитать. Если по какой-либо причине каталог нельзя открыть (например, у вас отсутствуют права на доступ к нему, либо просто указано имя несуществующего каталога), функция opendir возвращает значение false. При выборе имени дескриптора каталога следует руководствоваться теми же правилами, что й при выборе имени дескриптора файла (о них шла речь на 2-м занятии, "Строительные блоки Perl: числа и строки"). Всегда набирайте имя дескриптора прописными буквами, чтобы исключить возможный конфликт имен с ключевыми словами Perl, которые появятся в будущих версиях этого языка программирования., Вот пример .использования функции opendir: opendir (TEMPDIR, /tmp) { { die "01кбка пеи стьтзи кгтаа р: $!" ; Во всех примерах этого занятия в качестве разделителя пути мы используем косую черту (/), как это принято в системе UNIX. Причина заключается в том, что такой стиль написания улучшает читабельность листингов (поскольку нет конфликтов со служебным символом Perl \) и не нарушает работоспособность программ в системе Windows. .. После открытия каталога доступ к его содержимому можно получить с помощью функции readdir: : :• readdir дескриптор; . ; В скалярном контексте функция readdir возвращает следующий по эле- мент каталога или значение если достигнут конец каталога. В контексте списка функция readdir возвращает все оставщиеся элементы каталога! Имена; возвращаемые данной функцией, могут относиться как к файлам, так и к каталогам, а в системе UNIX - еще и к специальным файлам. Порядок их следования соответствует физическому расположению в каталоге. Другими словами, элементы каталога никак не сортируются. Кроме того, функция readdir возвращает еще два специальных элемента каталога: . и .. , которые соответствуют текущему и родительскому каталогам. В элементы каталога не включается путь. После завершения работы с каталогом его дескриптор следует закрыть с помощью функции closedir: closedir дескриптор, В следующем примере продемонстрирована методика чтения каталога: opendir(TEUPDIR, /tmp) die "Оийагиапьпиикатагсга/trip: $!"; griLES=readdlr TEMEDER; closedir(TEMPDIR); Здесь все содержимое каталога помещается в массив ШЬ!ЕЗ. Однако, чаще всего, из этого списка нужно исключить некоторые имена, например . и ... , поскольку для пользователя в них нет особого смысла. Для этого следует воспользоваться таким оператором чтения каталога: В этом примере регулярное выражение соответствует строке текста, в ко- торой находится как минимум одна точка. Функция grep отфильтровывает такие строки, поскольку перед регулярным выражением стоит оператор отрицания. Если нужно отобрать элементы каталога, содержащие заданное расширение, оператор чтения каталога будет выглядеть так: iFILES=grep(/\.txtS/i, readdir TEMPDIR) ; Имена файлов, возвращаемые функцией readdir, не содержат путь, который мы указывали в функции opendir при открытии каталога. Поэтому следующий пример, скорее всего, не будет работать: opendir(TEMPDIR, /tnp) die "QiK&a при сгечыпи кагашга /tnp: $1"; while(Sfile=readdir ТЕМЕПт) { t 11Б1аве1ЕЗЕ£Йя№ код неверен П! open(FlLEB, $file) II die QiK&a npi слчыпи4айга $file: $i\n; closedir(TEMPDIR); Кроме случаев, когда вы запускаете данную программу из каталога /tmp, при вы-нолнении оператора open(FILEH, $file) будет возникать ошибка. Причина состоит в том, что программа читает список файлов каталога /tmp, а оператор open пытается открыть файл в текущем каталоге. Естественно, что если текущим является не каталог /tmp и имена файлов текущего каталога и каталога /tmp не совпадают, то функция open не будет находить файлы. Для решения проблемы в операторе open следует указать полный путь к файлу. Правильный код будет выглядеть так: opendir(TEMPDIR, /tnp) die "Оиибка щм сотытии каталога /tnp: $ I"; while($file=readdir TEMPDIR) { # A этот кед уяе правнпьаый I open(FILEH, "/tmp/$file") jj die "Ошибка щм от1итии файла $file: ?(\n"; closedir(TEMPDI); Отбор файлов заданного типа Существует еще один метод получения списка нужнтх файлов заданного каталога, который называется отбором файлов (globbing). Если вы хоть немного работали с командной строкой DOS, то наверняка вам приходилось вводить команды наподобие dir *.txt. В данном случае команда dir выводит список всех файлов, имена котортх имеют расширение *txt В UNIX понятие расширения файла отсутствует, однако отбор нужн1х файлов также можно осуществить с помощью командной оболочки. Например, аналог приведенной выше команды dir в UNIX выглядит так: Is *.txt. В результате будет получен список всех файлов, имена которых оканчиваются суффиксом В Perl также предусмотрен специальный оператор glob, выполняющий описанные действия. Его синтаксис выглядит так: glob шаблон Здесь параметр шаблон соответствует именам файлов, которые необходимо отобрать. Он может содержать путь, а также часть имени файла. Кроме того, в шаблоне может быть указано несколько специальных символов, описанных в табл. 10.1. В контексте списка оператор glob возвращает имена всех файлов и каталогов, имена которых соответствуют шаблону. В скалярном контексте при каждом вызове описываемый оператор возвращает имя следующего файла, соответствующего шаблону. Не путайте шаблоны оператора glob это не одно и то же. с регулярными выражениями. Учтите, что Табца 10.1. Шабло оператора glob Свол Соответствует... Пример ? Одному символу * . Любому количеству символов [символы] Любому символу, указанному в списке. Данная возможность не поддерживается в MacPerl {строки} Любой строке, указанной в списке. Данная возможность не поддерживается в MacPerl Шаблон f?d соответствует именам fud, fid, fdd и т.д. Шаблон f*d соответствует именам fd, fdd, food, fdled и т.д. Шаблон f [ou]d соответствует именам fod или fud, но не fad Шаблон f*.{txt,doc} соответствует именам, которые начинаются на букву f и заканчиваются суффиксом .txtили .doc Это замечание относится к приверженцам UNIX. В операторег! glob реализована методика отбора файлов, принятая в оболочке С. Она немного отличается от методики, используемой в оболочке Bourne (или Когп). Данное замечание справедливо для всех платформ UNIX, на которых установлен Perl, независимо от того, в какой оболочке работает конечный пользователь. И хотя методики отбора файлов во многом схожи, отличия все же есть, главным образом в способе интерпретации символов шаблона * и ?. Поэтому будьте внимательны. Ниже приведено несколько примеров отбора файлов. f Выбфем все файлы .h из каталога /usr/include my §hfiles=glob(/usr/include/*.h); f A теперь отберем текстовые файлы, в именах которых i встречается 1999 год пу gci3rfiles=glob{*1999*.{txt,doc}); 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [ 46 ] 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |