| Содержание | Предисловие | В |
Глава 10В этой главе:
Открытие и закрытие дескриптора файла Небольшое отступление: функция die Использование дескрипторов файлов Операции для проверки файлов Функции stat и Istat Упражнения Дескрипторы файлов и проверка файловЧто такое дескриптор файла Дескриптор файла в Perl-программе — это имя соединения для ввода-вывода между вашим Perl-процессом и внешним миром. Мы уже видели дескрипторы файлов и пользовались ими, сами того не зна Имена дескрипторов файлов похожи на имена помеченных блоков, но они берутся из другого пространства имен (поэтому у вас может быть скаляр $fred, массив SОткрытие и закрытие дескриптора файла В Perl есть три дескриптора файлов, stdin, stdout и<open (ДЕСКРИПТОР,"имя") ;где дескриптор — новый дескриптор файла, а имя —open(OUT, ">выходной_файл");Мы увидим, как использовать этот дескриптор, в разделе "Использование дескрипторов файлов". Как и в shell, файл можно открытьopen (LOGFILE, "”мой_фаил_регчстрации") ;Все формы функции open в случае успешного выполнения возвращают значение "истина", а в случае неудачи —Закончив работать с дескриптором файла, вы можете закрыть его, воспользовавшись операцией close:close(LOGFILE) ; Попытка повторного открытия дескриптора файла приводит к автоматическому закрытию ранее открытого файла. Это же происходит и при выходе из программы. По этой причине многие Perl-программы не об Небольшое отступление: функция dieСчитайте этот раздел большой сноской, сделанной посреди страницы. Дескриптор файла, который не удалось успешно открыть, все равно может использоваться в программе, причем без каких-либо Скорее всего, вы захотите проверить результат выполнения функции open и получить сообщение об ошибке, если этот результат не оправдал ваши ожидания. Естественно, вы можете пunless (open (DATAPLACE,">/tmp/dataplace") ) ( print "Sorry, I couldn't create /tmp/dataplace\n"; } else { # остальная часть программы }Но это очень объемная задача, и встречается она достаточно часто, поэтому в Perl для нее предусмотрено специальное сокращение. Фунunless (open DATAPLACE,">/tmp/dataplace") f die "Sorry, I couldn't create /tmp/dataplace\n"; } * остальная часть программыМожно пойти еще дальше. Вспомним, что для сокращения записи можно использовать операцию | (логическое ИЛИ): open(DATAPLACE,">/tmp/dataplace") I I die "Sorry, I couldn't create /tmp/dataplace\n"; Таким образом, die выполняется только в том случае, если значение, получаемое в результате выполнения функции* Если вы не выполняете программу с ключом -w.** Фактически die просто генерирует исключение, но поскольку мы не показываем вам, как обрабатывать исключения, она ведет себя такК сообщению, выдаваемому в случае "смерти" (оно строится на основе аргумента функции die) автоматически присоединяется имя Perl-прdie "you gravy-sucking pigs"; выводит файл и номер строки, а die "you gravy-sucking pigs\n"; не выводит. Еще одна удобная штука внутри die-строк — переменная $!, которая содержит строку с описанием самой последней ошибки операционной системы. Используется она так:open (LOG, "”logfile") || die "cannot append: $!"; Например, в результате может быть выдано сообщение " cannot append:Permission denied". Имеется также функция "вызова при закрытии", которую большинство пользователей знают как warn. Она делает все, что делаетopen(LOG,"”log") 11 warn "discarding logfile output\n"; Использование дескрипторов файлов После того как дескриптор файла открыт для чтения, из него можно читать строки точно так же, как со стандартного ввода stdin.open (ЕР,"/etc/passwd");while (<EP>) ( chomp; print "I saw $_ in the password file!\n"; } Обратите внимание: вновь открытый дескриптор помещен в угловые скобки, аналогично тому как ранее мы использовали stdin.Если вы открыли дескриптор файла для записи или добавления и хотите ввести в него что-либо (с помощью функции print), этот дескрипprint LOGFILE "Finished item $n of $max\n"; print STDOUT "hi, world!\n"; # как print "hi, world!\n"В этом случае сообщение, начинающееся со слова Finished, посылается в дескриптор файла logfile,Предлагаем вам способ копирования данных из файла, заданного в переменной $а, в файл, указанный в переменной $Ь. Он иллюстрирует почти все, о чем мы рассказывали на последних нескольких страниц open(IN,$a) || die "cannot open $a for reading: $!"; open(OUT,">$b") || die "cannot create $b: $!"; while (<IN>) { # прочитать строку из файла $а в $_close (ОПТ) || die "can't close $b: $!";Операции для проверки файлов Теперь вы знаете, как открыть дескриптор файла для вывода, уничтожив существующий файл с таким же именем. Предположим, вы хотите удостовериться, что файла с таким именем не существует ( $name = "index.html"; if (-e $name) ( print "I see you already have a file named $name\n"; } else ( print "Perhaps you'd like to make a file called $name\n"; } * Хотя при наличии модуля File:: Copy этот способ оказывается лишним.** Это не совсем хорошо, если вы работаете с lock-файлами или если файлы часто появляются и исчезают. В этом случае вам нужно обратиться к функциям sysopОперанд операции -е — любое скалярное выражение, вычисление которого дает некоторую строку, включая строковый литерал. Вот пример,if (-е "index.html" && -е "index.cgi") (print "You have both styles of index files here.\n"; 1 Существуют и другие операции. Например, -r $filevar возвращает значение "истина", если заданный в $fprint "where? "; $filename “ <STDIN>; chomp $filename; # выбросить этот надоедливый символ новой строки if (-r $filename &S -w $filename) (# } Есть много других операций для проверки файлов. Полный перечень их приведен в таблице 10.1.Таблица 10.1. Операции для проверки файлов и их описание
Большинство этих проверок возвращает просто значение "истина" или "ложь". О тех, которые этого не делают, мы сейчас поговорим. Операция -s возвращает значение "истина", если файл непустой, но это значение особого вида. Это длина файла в байтах, которая интерпретируется как "истина" при ненулевом знаОперации -м, -а и -с (да-да, в верхнем регистре) возвращают количество дней соответственно с момента последнего изменения файла, доступа к нему и изменения его индексного дескриптора*. (Индексный дескриптор содержит всю информацию о фай * Эти значения определяются относительно времени запуска программы, занесенного в системном формате времени в переменную $соответствующее прошедшему времени с точностью до 1 секунды: 36 часЭти операции могут работать не только с именами файлов, но и с дескрипторами. Для этого нужно просто указать в качестве операнда дескриптор файла. Так, чтобы проверить, доступен ли для выполнения файл, открытый как sif (-х SOMEFILE) (# файл, открытый как SOMEFILE, доступен для выполнения} Если имя или дескриптор файла не указаны (т.е. даны только операции *г или -s), то по умолчанию в качестве операнда берется файл, указанный в переменной $_ (опять эта переменная!foreach (@some_list_of_filenames) ( print "5_ is readable\n" if -r; # то же, что и -г $_ >Функции stat и IstatВышеупомянутые операции весьма эффективны при проверке различных атрибутов конкретного файла или дескриптора файла, но полную информацию с их помощью получить нельзя. Например, не преду Операнд функции stat — дескриптор файла или выражение, посредством которого определяется имя файла. Возвращаемое значение — Или операцию int.** Если вам тяжело запомнить порядок значений, возвращаемых функцией stat, можете обратиться к модулю File: :s$file_owner = stat($filename)->uid Имена здесь соответствуют частям структуры stat, подробно описанной на man-странице stat(T).($uid,,$gid) = (stat("/etc/passwd")) [4,5]; и этого окажется достаточно. Вызов функции stat с именем символической ссылки возвращает информацию о том, на что указывает эта ссылка, а не сведения о самой ссылке (если только она не указывает на что-Как и в операциях проверки файлов, операнд функций stat и Istat поУпражнения Ответы приведены в приложении А. 1. Напишите программу чтения имени файла из stdin, открытия этого файла и выдачи его содержимого с предварение2. Напишите программу, которая приглашает ввести имя входного файла, имя выходного файла, образец поиска и заменяющую строку, после чего копирует входной файл в выходной, за3. Напишите программу чтения списка имен файлов и выдачи информации о том, какие файлы доступны для чтения, для записи и (или) для выполнения, а какие файлы не существуют. (4. Напишите программу чтения списка имен файлов и поиска среди них самого старого. Выведите на экран имя файла и его возраст в днях.
| Содержание | Предисловие | В
| |