Шрифт:
DIR *opendir(const char *name); /* Открыть каталог для чтения */
struct dirent *readdir(DIR *dir); /* Вернуть struct dirent за раз */
int closedir(DIR *dir); /* Закрыть открытый каталог */
void rewinddir(DIR *dirp); /* Вернуться в начало каталога */
Тип
DIR
является аналогом типа FILE
в <stdio.h>
. Это непрозрачный тип, что означает, что код приложения не должен знать, что находится внутри него; его содержимое предназначено для использования другими процедурами каталогов. Если opendir
возвращает NULL
, именованный каталог не может быть открыт для чтения, а errno содержит код ошибки. Открыв переменную
DIR*
, можно использовать ее для получения указателя на struct dirent
, представляющего следующий элемент каталога. readdir
возвращает NULL
, если достигнут конец каталога [54] или произошла ошибка. Наконец,
closedir
является аналогичной функции fclose
в <stdio.h>
; она закрывает открытую переменную DIR*
. Чтобы начать с начала каталога, можно использовать функцию rewinddir
.54
То есть прочитаны все элементы каталога — Примеч. науч. ред.
Имея в распоряжении (или по крайней мере в библиотеке С) эти функции, мы можем написать небольшую программу
catdir
, которая «отображает» содержимое каталога. Такая программа представлена в ch05-catdir.с
:
1 /* ch05-catdir.с - Демонстрация opendir, readdir, closedir. */
2
3 #include <stdio.h> /* для printf и т.д. */
4 #include <errno.h> /* для errno */
5 #include <sys/types.h> /* для системных типов */
6 #include <dirent.h> /* для функций каталога */
7
8 char *myname;
9 int process(char *dir);
10
11 /* main --- перечисление аргументов каталога */
12
13 int main(int argc, char **argv)
14 {
15 int i;
16 int errs = 0;
17
18 myname = argv[0];
19
20 if (argc == 1)
21 errs = process("."); /* по умолчанию текущий каталог */
22 else
23 for (i = 1; i < argc; i++)
24 errs += process(argv[i]);
25
26 return (errs != 0);
27 }
Эта программа вполне подобна
ch04-cat.c
(см. раздел 4.2 «Представление базовой структуры программы»); функция main
почти идентична. Главное различие в том, что по умолчанию используется текущий каталог, если нет аргументов (строки 20–21).
29 /*
30 * process --- сделать что-то с каталогом, в данном случае,
31 * вывести пары индекс/имя в стандартный вывод.
32 * Возвращает 0, если все OK, иначе 1.
33 */
34
35 int
36 process(char *dir)
37 {
38 DIR *dp;
39 struct dirent *ent;
40
41 if ((dp = opendir(dir)) == NULL) {
42 fprintf(stderr, "%s: %s: cannot open for reading: %s\n",
43 myname, dir, strerror(errno));
44 return 1;
45 }
46
47 errno = 0;
48 while ((ent = readdir(dp)) != NULL)
49 printf("%8ld %s\n", ent->d_ino, ent->d_name);
50
51 if (errno != 0) {
52 fprintf(stderr, "%s: %s: reading directory entries: %s\n",
53 myname, dir, strerror(errno));
54 return 1;
55 }
56
57 if (closedir(dp) != 0) {
58 fprintf(stderr, "%s: %s: closedir: %s\n",
59 myname, dir, strerror(errno));
60 return 1;
61 }
62