Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

14.4. Чтение содержимого каталога

Обычно программам требуется получать список файлов, содержащихся в каталоге. Linux предоставляет ряд функций, позволяющих обрабатывать каталог как абстрактный объект, что дает возможность избежать зависимости программ от точного формата каталогов, реализуемого файловой системой. Открытие и закрытие каталогов осуществляется очень просто.

#include <dirent.h>

DIR * opendir(const char * pathname);

int closedir(DIR * dir);

Системный вызов

opendir
возвращает указатель на тип данных
DIR
, который является абстрактным (как и структура
stdio
по имени
FILE
) и которым не следует манипулировать вне библиотеки С. Поскольку каталоги можно открывать только для чтения, нет необходимости определять, в каком режиме открывается каталог,
opendir
срабатывает только в случае существования каталога — этот вызов нельзя использовать для создания новых каталогов (для этого служит
mkdir
). Закрытие каталога может не сработать только в случае некорректного значения аргумента
dir
.

После открытия каталога его элементы читаются последовательно до конца каталога.

Системный вызов

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

#include <dirent.h>

struct dirent * readdir (DIR * dir);

Вызывающему коду возвращается указатель на структуру

struct dirent
. Несмотря на то что
struct dirent
содержит несколько элементов, единственным переносимым элементом является
d_name
, содержащий имя файла элемента каталога. Остальные элементы
struct dirent
зависят от системы. Однако интересным является элемент
d_ino
, содержащий inode-номер файла.

Самой сложной частью этого процесса является определение ошибки. К сожалению,

readdir
возвращает
NULL
, и когда происходит ошибка, и когда в каталоге больше нет элементов. Чтобы различать эти две ситуации, необходимо проверять
errno
. Эта задача усложняется тем, что
readdir
не меняет
errno
, пока не произойдет ошибка. Это означает, что для корректной проверки ошибок
errno
необходимо установить перед вызовом
readdir
в заранее известное значение (обычно 0). Ниже показана простая программа, записывающая имена файлов текущего каталога в stdout.

 1: /* dircontents.с */

 2:

 3: #include <errno.h>

 4: #include <dirent.h>

 5: #include <stdio.h>

 6:

 7: int main(void) {

 8: DIR * dir;

 9: struct dirent * ent;

10:

11: /* "." - текущий каталог */

12: if (!(dir = opendir("."))) {

13: perror("opendir");

14: return 1;

15: }

16:

17: /* установить errno в 0, чтобы можно было выяснить, когда readdir даст сбой*/

18: errno = 0;

19: while ((ent = readdir(dir))) {

20: puts (ent->d_name);

21: /* сбросить errno, поскольку puts может модифицировать ее */

22: errno = 0;

23: }

24:

25: if (errno) {

26: perror("readdir");

27: return 1;

28: }

29:

30: closedir(dir);

31:

32: return 0;

33: }

14.4.1. Прохождение по каталогу

Если требуется перечитать содержимое каталога, уже открытого

opendir
, с помощью
rewinddir
структура
DIR
сбрасывается, чтобы следующий вызов
readdir
мог вернуть первый файл в каталоге.

#include <dirent.h>

int rewinddir(DIR * dir);

14.5. Универсализация файловых имен

Большинство пользователей Linux принимают как должное то, что запуск

ls *.с
не сообщает сведения о файле в текущем каталоге, именем которого является
*.с
. Вместо этого они ожидают увидеть список всех файлов в текущем каталоге, имена которых заканчиваются на
.с
. Это расширение имени файла от
*.с
до
ladsh.с dircontents.с
(например) обычно обрабатывается оболочкой, которая универсализирует все параметры для программ, выполняющихся под ее управлением. Программы, помогающие пользователям манипулировать файлами, тоже часто нуждаются в универсализации файловых имен. Существуют два распространенных способа универсализации имен файлов внутри программ.

  • Читать дальше
  • 1
  • ...
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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