Операции для проверки файлов
Теперь вы знаете, как открыть дескриптор файла для вывода, уничтожив существующий файл с таким же именем. Предположим, вы хотите удостовериться, что файла с таким именем не существует (чтобы избежать случайного уничтожения своей электронной таблицы или очень важного календаря дней рождений). Если бы вы писали сценарий shell, вы использовали бы для проверки существования файла нечто вроде -е имя_фаила. Аналогичным образом в Perl применяется операция -е $filevar,
которая проверяет факт существования файла, заданного в скалярной переменной $filevar.
Если этот файл существует, результат — "истина"; в противном случае операция дает "ложь"**. Например:
$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-файлами или если файлы часто появляются и исчезают. В этом случае вам нужно обратиться к функциям sysopen и flock, которые описаны в книге Programming Perl, или изучить примеры, приведенные в главе 19.
Операнд операции -е — любое скалярное выражение, вычисление которого дает некоторую строку, включая строковый литерал. Вот пример, в котором проверяется наличие файлов index-html и index.cgi
в текущем каталоге:
if (-е "index.html" && -е "index.cgi") (
print "You have both styles of index files here.\n";
1
Существуют и другие операции. Например, -r $filevar возвращает значение "истина", если заданный в $filevar
файл существует и может быть прочитан. Операция -w $filevar проверяет возможность записи в файл. В следующем примере файл с заданным пользователем именем проверяется на возможность чтения и записи:
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 возвращает значение "истина", если файл непустой, но это значение особого вида. Это длина файла в байтах, которая интерпретируется как "истина" при ненулевом значении.
Операции -м, -а и -с (да-да, в верхнем регистре) возвращают количество дней соответственно с момента последнего изменения файла, доступа к нему и изменения его индексного дескриптора*. (Индексный дескриптор содержит всю информацию о файле; подробности см. на man-странице, посвященной системному вызову stat.) Возвращаемое значение — десятичное число,
* Эти значения определяются относительно времени запуска программы, занесенного в системном формате времени в переменную $ "т.
Если запрашиваемое значение относится к событию, которое произошло после начала работы программы, оно может быть отрицательным.
соответствующее прошедшему времени с точностью до 1 секунды: 36 часов возвращается как 1,5 дня. Если при отборе файлов будет выполнено сравнение этого показателя с целым числом (например, с 3), то вы получите только те файлы, которые были изменены ровно столько дней назад, ни секундой раньше и ни секундой позже. Это значит, что для получения всех файлов, значение определенного показателя для которых находится в диапазоне от трех до четырех дней, вам, вероятно, нужно будет использовать операцию сравнения диапазонов*, а не операцию сравнения значений.
Эти операции могут работать не только с именами файлов, но и с дескрипторами. Для этого нужно просто указать в качестве операнда дескриптор файла. Так, чтобы проверить, доступен ли для выполнения файл, открытый как somefile, можно сделать следующее:
if (-х SOMEFILE) (
# файл, открытый как SOMEFILE, доступен для выполнения
}
Если имя или дескриптор файла не указаны (т.е. даны только операции
*г или -s), то по умолчанию в качестве операнда берется файл, указанный в переменной $_ (опять эта переменная!). Так, чтобы проверить список имен файлов и установить, какие из них доступны для чтения, нужно просто-напросто написать следующее:
foreach (@some_list_of_filenames) (
print "5_ is readable\n" if -r; # то же, что и -г $_ >