Получение информации о файле

В файловой системе UNIX информация о файле хранится в его индексном дескрипторе (inode). Структура индексного дескриптора состоит из 13 полей, для которых используются специальные обозначения. Все они перечислены в табл. 6.2 с кратким описанием.
Таблица 6.2. Структура индексного дескриптора файла
Поле Описание
dev Номер устройства в файловой системе
ino Номер индексного дескриптора
mode Режим файла (тип и права доступа)
nlink Количество жестких ссылок на файл (в отсутствии ссылок равно 1)
uid Числовой идентификатор владельца файла
gid Числовой идентификатор группы владельца файла
rdev Идентификатор устройства (только для специальных файлов)
size Размер файла в байтах
atime Время последнего обращения к файлу с начала эпохи
mtime Время последнего изменения файла с начала эпохи
ctime Время изменения индексного дескриптора с начала эпохи
blksize Предпочтительный размер блока для операций ввода-вывода
blocks Фактическое количество выделенных блоков для размещения файла
ВНИМАНИЕ Некоторые из перечисленных в табл. 6.2 полей структуры индексного дескриптора поддерживаются не всеми файловыми системами.
Для получения значений полей структуры индексного дескриптора файла в Perl существует стандартная функция stat( ). Ее единственным параметром может быть либо имя файла, либо дескриптор открытого в программе файла. Она возвращает в списковом контексте список из 13 элементов, содержащих значения полей структуры индексного дескриптора файла в том порядке, как они перечислены в табл. 6.2. Типичное использование этой функции в программе Perl выглядит следующим образом:
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,
$mtime,$ctime,$blksize,$blocks) = stat($filename);
Если при обращении к функции stat( ) не указан параметр, то она возвращает структуру индексного дескриптора файла, имя которого содержится в специальной переменной $_.
Функция получения информации о файле при успешном выполнении в списковом контексте возвращает список значений полей структуры индексного дескриптора файла или пустой список в случае неудачного завершения. В скалярном контексте она возвращает булево значение «истинам или «ложь» в зависимости от успешности или не успешности своего выполнения.
Сделаем замечание относительно третьего поля в структуре индексного дескриптора файла. Его значение определяет не только режим доступа к файлу, но также и тип этого файла. Поэтому, если необходимо выделить из него восьмеричное значение режима доступа, следует воспользоваться операцией побитового И с восьмеричным 07777:
$mode = (stat("out.dat"))[2];
printf "Permissions are %04o\n",  $mode & 07777:
В этом фрагменте для вывода восьмеричного числа мы воспользовались форматной функцией вывода printf, которая полностью соответствует своему аналогу в языке С, использовав в ней формат %04о для вывода восьмеричных чисел в виде 0хххх. Заметим, что в языке есть функция sprintf, действие которой аналогично действию функции printf за исключением того, что вывод осуществляется не на стандартное устройство вывода или в файл, определяемый дескриптором, а в скалярную переменную, которую в дальнейшем можно распечатать. По существу, функция printf( ) реализуется вызовом функции print с параметром, являющимся результатом выполнения функции sprintf( ):
print ДЕСКРИПТОР sprintf (CTPOКА_ФOPMATOB, СПИСОК);
Для удобства использования информации о файле функция stat( ) при успешном выполнении кэширует полученные значения полей. Если вызвать эту функцию со специальным дескриптором файла _ (символ подчеркивания), то она возвратит информацию, хранящуюся в кэше от предыдущего ее вызова. Это позволяет проверять различные атрибуты файла без повторного вызова функции stat ( ) или сохранения результатов ее выполнения в переменных программы.
Функцию stat( ) можно использовать для получения структуры индексного дескриптора не только файла, но и жестких ссылок на него, а также каталогов, так как они тоже являются файлами, блоки данных которых содержат имена файлов каталога и их числовых индексных дескрипторов.
Для получения информации о символических ссылках следует использовать функцию lstat( ), которая возвращает список значений полей структуры индексного дескриптора самой ссылки, а не файла, на который она ссылается. Эта функция работает аналогично функции stat( ), включая использование специального файлового дескриптора _.
ПРИМЕЧАНИЕ Если операционная система не поддерживает символические ссылки, то обращение к функции lstat( ) заменяется обращением к функции stat( ).
Кроме двух этих функций, позволяющих получать информацию о файлах системы, в Perl предусмотрен набор унарных операций, возвращающих значение только одного поля структуры индексного дескриптора. Эти операции в документации называются «операциями -X», так как их названия состоят из дефиса с последующим единственным символом. Синтаксис вызова этих операций может принимать одну из следующих форм:
-X ОПЕРАНД
-Х(ОПЕРАНД)
Все они являются унарными именованными операциями, поэтому в выражениях рекомендуется их единственный операнд заключать в круглые скобки, дабы не возникли неясности и неточности в вычислении всего выражения в связи с приоритетом выполнения этих операций.
Полный список унарных именованных операций проверки атрибутов файлов представлен в табл. 6,3.
Таблица 6.3. Унарные именованные операции проверки файлов
-r Файл доступен для чтения под текущим uid/gid -w Файл доступен для записи под текущим uid/gid
-x Файл доступен для выполнения под текущим uid/gid -o Текущий uid является владельцем файла
-R Файл доступен для чтения реальному uid/gid -W Файл доступен для записи реальному uid/gid
-X Файл доступен для выполнения реальному uid/gid -O Реальный uid является владельцем файла
-e Файл существует -z Файл имеет нулевой размер
-s Файл имеет ненулевой размер (возвращает длину файла) -f Это простой файл?
-l Это символьная ссылка? -d Это каталог?
-S Это гнездо? -p Это именованный канал (FIFO)
-c Это специальный символьно-ориентированный файл? -b Это специальный блок-ориентированный файл?
-u Установлен бит setuid? -t Указатель файла связан с tty
-k Установлен бит липучки? -g Установлен бит setgid?
-T Это текстовый файл? -B Это двоичный файл? (противоположность -Т)
-M Возраст файла в днях на момент запуска программы -A То же, но для времени доступа к файлу
-C То же, для времени изменения inode    
Операндом любой унарной операции проверки атрибутов файла является либо строка, содержащая имя файла, либо выражение, вычисляемое строковое значение которой трактуется как имя файла, либо файловый дескриптор Perl. Если операнд операции не задан, то она тестирует файл, имя которого содержится в специальной переменной $_. Каждая операция проверки атрибута файла возвращает 1, если файл обладает соответствующим атрибутом, пустую строку "" в противном случае и неопределенное значение undef, если указанный в операнде файл не существует.
Несколько слов об алгоритме определения текстовых и двоичных файлов, применяемом в операциях -Т и -B. Эти операции анализируют содержимое первого блока файла на наличие «странных» символов — необычных управляющих последовательностей или байтов с установленными старшими битами. Если обнаружено достаточно большое количество подобных символов (больше 30%), то файл считается двоичным, иначе — текстовым. Любой файл с пустым первым блоком рассматривается как двоичный. Если эти операции применяются к файловым дескрипторам Perl, то проверяется содержимое буфера ввода-вывода, а не первого блока файла. Обе эти операции, примененные к файловым дескрипторам, возвращают булево значение «истина», если связанный с дескриптором файл пуст или установлен на конец файла.
При выполнении унарных именованных операций проверки файла так же, как и в случае функции stat( ), можно использовать специальный файловый дескриптор _ (символ подчеркивания), в котором сохраняются атрибуты файла, проверяемого предыдущей операцией проверки файлов. Использование этого специального дескриптора позволяет ускорить операции множественных проверок файла, исключив соответствующие системные вызовы:
foreach $filename (@ARGV) { 
  if( -e($filename) && -T _) { 
    # Обрабатываем текстовые файлы ненулевого размера.
    print "$filename\n";
  }
}
В этом фрагменте в цикле foreach из специального массива @ARGV «читаются» имена файлов, и для каждого файла проверяется, существует ли он и является ли он текстовым файлом. В случае успешности проверки печатается имя файла. Имена файлов в этот сценарий могут быть переданы, например, при его запуске из командной строки.
ВНИМАНИЕ Имена файлов во всех унарных операциях проверки файлов должны быть представлены полными именами. Если задано относительное имя файла, то оно рассматривается как имя файла каталога, который являлся текущим во время запуска сценария, если только в самом сценарии функцией chdir( ) он не был изменен.

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


Реклама