| Содержание | Предисловие | В

Глава 10

    В этой главе:


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

Что такое дескриптор файла

Дескриптор файла в 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>) { # прочитать строку из файла $а в $_

print ОПТ $_; # вывести эту строку в файл $Ь ) close(IN) || die "can't close $a: $!";

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 возвращает значение "истина", если заданный в $f

print "where? ";

$filename “ <STDIN>;

chomp $filename; # выбросить этот надоедливый символ новой строки if (-r $filename &S -w $filename) (

# файл существует, я могу читать его и записывать в него

}

Есть много других операций для проверки файлов. Полный перечень их приведен в таблице 10.1.

Таблица 10.1. Операции для проверки файлов и их описание

Обозначение

Описание

-r

Файл или каталог доступен для чтения

-w

Файл или каталог доступен для записи

-X

Файл или каталог доступен для выполнения

Файл или каталог принадлежит владельцу

-R

Файл или каталог доступен для чтения реальным пользователем, но не "эффективным" пользователем (отличается от -r для программ с установленным битом смены

-W

Файл или каталог доступен для записи реальным пользователем, но не "эффективным" пользователем (отличается от -w для программ с установленным битом смены

-X

Файл или каталог доступен для выполнения реальным пользователем, но не "эффективным" пользователем (отличается от -х для программ с установленным битом смены идентификатора пользователя)

-0

Файл или каталог принадлежит реальному пользователю, но не "эффективному"пользователю (отличается от -о для программ с установленным битом смены идентификатора пользователя)

Обозначение

Описание

Файл или каталог существует

-2

Файл существует и имеет нулевой размер (каталоги пустыми не бывают)

-s

Файл или каталог существует и имеет ненулевой размер (значение размер в байтах)

-f

Данный элемент обычный файл

-d

Данный элемент каталог

-1

Данный элемент символическая ссылка

-S

Данный элемент порт

-P

Данный элемент именованный канал (FIFO-файл)

-b

Данный элемент блок-ориентированный файл (например, монтируемый диск)

Данный элемент байт-ориентированный файл (например, файл устройства ввода-вывода)

-u

У файла или каталога установлен идентификатор пользо

 

 

вателя

-g

У файла или каталога установлен идентификатор группы

-k

У файла или каталога установлен бит-липучка

-t

Выполнение операции isatty() над дескриптором файла дало значение "истина"

-T

Файл текстовый

-B

Файл двоичный

-M

Время с момента последнего изменения (в днях)

-A

Время с момента последнего доступа (в днях)

-C

Время с момента последнего изменения индексного дескриптора (в днях)

 

Большинство этих проверок возвращает просто значение "истина" или "ложь". О тех, которые этого не делают, мы сейчас поговорим.

Операция -s возвращает значение "истина", если файл непустой, но это значение особого вида. Это длина файла в байтах, которая интерпретируется как "истина" при ненулевом зна

Операции -м, -а и -с (да-да, в верхнем регистре) возвращают количество дней соответственно с момента последнего изменения файла, доступа к нему и изменения его индексного дескриптора*. (Индексный дескриптор содержит всю информацию о фай

* Эти значения определяются относительно времени запуска программы, занесенного в системном формате времени в переменную $

соответствующее прошедшему времени с точностью до 1 секунды: 36 час

Эти операции могут работать не только с именами файлов, но и с дескрипторами. Для этого нужно просто указать в качестве операнда дескриптор файла. Так, чтобы проверить, доступен ли для выполнения файл, открытый как s

if (-х 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. Напишите программу чтения списка имен файлов и поиска среди них самого старого. Выведите на экран имя файла и его возраст в днях.




|     Назад     |
| Содержание | Предисловие | В



Сайт создан в системе uCoz