Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

globLastArgument(prog, &argc, &argvAlloced);

Полный код

ladsh3.с
доступен на Web-сайте издательства, а также на сайте, посвященном книге.

14.7. Обход деревьев файловых систем

Существуют две функции, которые облегчают приложениям просмотр всех файлов каталога, включая файлы в подкаталогах. Рекурсивный просмотр всех элементов древовидной структуры (например, файловой системы) часто называется обходом (walk) дерева и он реализуется функциями

ftw
и
nftw
.
nftw
представляет собой усовершенствованную версию
ftw
.

14.7.1. Использование

ftw

#include <ftw.h>

int ftw(const char *dir, ftwFunctionPointer callback, int depth);

Функция

ftw
начинает с каталога
dir
и вызывает указанную в
callback
функцию для каждого файла в этом каталоге и его подкаталогах. Функция вызывается для всех типов файлов, включая символические ссылки и каталоги. Реализация
ftw
открывает каждый найденный каталог (с помощью файлового дескриптора) и для увеличения производительности не закрывает их, пока не закончит чтение всех элементов каталога. Это означает, что он использует количество файловых дескрипторов, равное количеству уровней подкаталогов. Чтобы предотвратить недостаток файловых дескрипторов в приложении, параметр
depth
ограничивает количество файловых дескрипторов
ftw
, остающихся одновременно открытыми. Если этот предел достигается, производительность снижается, поскольку каталоги необходимо часто открывать и закрывать.

Функция, на которую указывает

callback
, определяется следующим образом:

int ftwCallbackFunction(const char * file, const struct stat * sb, int flag);

Эта функция вызывается один раз для каждого файла в дереве каталогов, а первый параметр,

file
, представляет собой имя файла, начинающееся с
dir
, которое передается
ftw
. Например, если бы аргумент
dir
принимал значение
.
, одним из файловых имен было бы .
/bashrc
. Если бы вместо этого использовалось
/etc
, имя файла выглядело бы как
/etc/hosts
.

Следующий аргумент обратного вызова,

sb
, указывает на структуру
struct stat
как на результат применения
stat
к файлу [102] . Аргумент
flag
предоставляет информацию о файле и принимает одно из следующих значений.

FTW_F
Файл не является символической ссылкой или каталогом.
FTW_D
Файл является каталогом либо символической ссылкой, указывающей на каталог.
FTW_DNR
Файл является каталогом, полномочий на чтение которого у приложения нет (то есть его обход невозможен).
FTW_SL
Файл является символической ссылкой.
FTW_NS
Файл является объектом, к которому не удалось применить
stat
. Примером может служить файл в каталоге, права на чтение которого приложение имеет (приложение может получить список файлов этого каталога), но не имеет права на выполнение (что предотвращает успешный вызов
stat
применительно к файлам этого каталога).

102

Функции

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

Когда файл является символической ссылкой,

ftw
пытается последовать за этой ссылкой и вернуть информацию о файле, на который она указывает (
ftw
проходит один и тот же каталог несколько раз, если на него имеется несколько символических ссылок). Однако для поврежденной ссылки не определено, вернется
FTW_SL
или
FTW_NS
. Это хорошая причина, чтобы использовать
nftw
.

Если функция обратного вызова возвращает ноль, обход каталога продолжается. Если возвращается ненулевое значение, обход дерева файлов завершается и эта величина возвращается функцией

ftw
. При удачном завершении обхода
ftw
возвращает ноль, а в случае ошибки возвращается -1.

14.7.2. Обход дерева файлов с помощью

nft

Новая версия

ftw
nftw
решает неоднозначность символических ссылок, присущих
ftw
, и содержит несколько дополнительных свойств. С целью правильного определения
nftw
заголовочными файлами значение
_XOPEN_SOURCE
в приложении должно быть определено 500 или больше. Ниже показан прототип
nftw
.

#define _XOPEN_SOURCE 600

#include <ftw.h>

int nftw(const char * dir, ftwFunctionPointer callback, int depth, int flags);

int nftwCallbackFunction(const char *file, const struct stat * sb,

 int flag, struct FTW * ftwInfo);

Сравнивая

nftw
с
ftw
, легко заметить новый параметр —
flags
. Это может быть один или несколько следующих флагов, объединенных с помощью логического "ИЛИ".

FTW_CHDIR
Функция
nftw
обычно не меняет текущий каталог программы. Если определен флаг
FTW_CHDIR
функция
nftw
меняет текущий каталог на любой другой каталог, читаемый в данный момент. Иначе говоря, при активизации обратного вызова имя файла, передаваемое ему, всегда относится к текущему каталогу.
FTW_DEPTH
По умолчанию
nftw
выводит имя каталога перед списком имен файлов в этом каталоге. Этот флаг вызывает изменение порядка на обратный, то есть содержимое каталога выводится перед его именем. (Примечание. Этот флаг заставляет
nftw
выполнять поиск в глубину. Подобного флага для поиска в ширину не существует.)
FTW_MOUNT
Это флаг запрещает
nftw
переходить границу файловой системы во время обхода. Более подробно файловые системы описаны в [32].
FTW_PHYS
Вместо следования символическим ссылкам
nftw
сообщает о ссылках, но не следует по ним. Побочный эффект заключается в том, что обратный вызов получает результат вызова
lstat
, а не
stat
.

Аргумент обратного вызова

flag
может принимать два новых значения для
nftw
вдобавок к значениям, уже упомянутым для
ftw
.

FTW_DP
Этот элемент является каталогом, об оглавлении которого уже сообщили (это может произойти только в случае установки
FTW_DEPTH
).
FTW_SLN
Этот элемент является символической ссылкой, указывающей на несуществующий файл (поврежденная ссылка). Это происходит только в том случае, если
FTW_PHYS
не был установлен; если же он был установлен, передается
FTW_SL
.

Эти дополнительные значения

flag
надлежащим образом определяют
nftw
для символических ссылок. При использовании
FTW_PHYS
все символические ссылки возвращают
FTW_SL
. Без
nftw
поврежденные ссылки выдают
FTW_NS
, а другие символические ссылки дают тот же результат, что и цель ссылки.

Обратный вызов для

nftw
принимает еще один аргумент,
ftwInfо
. Это указатель на
struct FTW
, которая определяется следующим образом.

#define _XOPEN_SOURCE 600

#include <ftw.h>

struct FTW {

 int base;

 int level;

};

Элемент

base
— это смещение имени файла в полном пути, передаваемое обратному вызову. Например, если переданный полный путь выглядит как
/usr/bin/ls
,
base
будет равно 9, a
file + ftwInfo->base
даст имя файла
ls
.
level
— это количество каталогов под текущим каталогом. Если
ls
был найден в
nftw
, начинающемся с
/usr
, уровень будет равен 1. Если поиск начался с
/usr/bin
, уровень будет равен 0.

Поделиться:
Популярные книги

Дракон с подарком

Суббота Светлана
3. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
6.62
рейтинг книги
Дракон с подарком

Бывшие. Война в академии магии

Берг Александра
2. Измены
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Бывшие. Война в академии магии

Мастер клинков. Начало пути

Распопов Дмитрий Викторович
1. Мастер клинков
Фантастика:
фэнтези
9.16
рейтинг книги
Мастер клинков. Начало пути

Имя нам Легион. Том 8

Дорничев Дмитрий
8. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 8

Измена. Право на счастье

Вирго Софи
1. Чем закончится измена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на счастье

Начальник милиции 2

Дамиров Рафаэль
2. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции 2

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Измена. Мой заклятый дракон

Марлин Юлия
Любовные романы:
любовно-фантастические романы
7.50
рейтинг книги
Измена. Мой заклятый дракон

Предатель. Цена ошибки

Кучер Ая
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Предатель. Цена ошибки

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Рождение победителя

Каменистый Артем
3. Девятый
Фантастика:
фэнтези
альтернативная история
9.07
рейтинг книги
Рождение победителя

Барону наплевать на правила

Ренгач Евгений
7. Закон сильного
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Барону наплевать на правила

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь