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

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

Жанры

Linux программирование в примерах
Шрифт:

70 ++Errors;

71 close(fd);

72 return;

73 }

74 close(fd);

В строке 60 каталог открывается для чтения (второй аргумент равен 0, что означает

O_RDONLY
). В строке 65 читается
struct direct
. В строке 66 проверяется, не является ли элемент каталога пустым, т. е. с номером индекса 0. Строки 67 и 68 проверяют на наличие '
.
' и '
..
'. По достижении строки 69 мы знаем, что было встречено какое-то другое имя файла, следовательно, этот каталог не пустой.

(Тест '

!strcmp(s1, s2)
'
является более короткой формой '
strcmp(s1, s2) == 0
', т.е. проверкой совпадения строк. Стоит заметить, что мы рассматриваем '
!strcmp(s1, s2)
' как плохой стиль. Как сказал однажды Генри Спенсер (Henry Spencer), «
strcmp
это не boolean!».)

Когда 4.2 BSD представило новый формат файловой системы, который допускал длинные имена файлов и обеспечивал лучшую производительность, были также представлены несколько новых функций для абстрагирования чтения каталогов. Этот набор функций можно использовать независимо от того, какова лежащая в основе файловая система и как организованы каталоги. Основная ее часть стандартизована POSIX, а программы, использующие ее, переносимы между системами GNU/Linux и Unix.

5.3.1. Базовое чтение каталогов

Элементы каталогов представлены

struct dirent
(не то же самое, что V7
struct direct
!):

struct dirent {

 ...

 ino_t d_ino; /* расширение XSI --- см. текст */

 char d_name[...]; /* О размере этого массива см. в тексте */

 ...

};

Для переносимости POSIX указывает лишь поле

d_name
, которое является завершающимся нулем массивом байтов, представляющим часть элемента каталога с именем файла. Размер
d_name
стандартом не указывается, кроме того, что там перед завершающим нулем может быть не более
NAME_MAX
байтов. (
NAME_MAX
определен в
<limits.h>
.) Расширение XSI POSIX предусматривает поле номера индекса
d_ino
.

На практике, поскольку имена файлов могут быть различной длины, a

NAME_MAX
обычно довольно велико (подобно 255),
struct dirent
содержит дополнительные члены, которые помогают вести на диске учет элементов каталогов с переменными длинами. Эти дополнительные члены не существенны для обычного кода.

Следующие функции предоставляют интерфейс чтения каталогов:

#include <sys/types.h> /* POSIX */

#include <dirent.h>

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

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

Его наследник

Безрукова Елена
1. Наследники Сильных
Любовные романы:
современные любовные романы
эро литература
5.87
рейтинг книги
Его наследник

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Я – Орк. Том 4

Лисицин Евгений
4. Я — Орк
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 4

Кротовский, не начинайте

Парсиев Дмитрий
2. РОС: Изнанка Империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, не начинайте

Я тебя верну

Вечная Ольга
2. Сага о подсолнухах
Любовные романы:
современные любовные романы
эро литература
5.50
рейтинг книги
Я тебя верну

Звезда сомнительного счастья

Шах Ольга
Фантастика:
фэнтези
6.00
рейтинг книги
Звезда сомнительного счастья

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Real-Rpg. Еретик

Жгулёв Пётр Николаевич
2. Real-Rpg
Фантастика:
фэнтези
8.19
рейтинг книги
Real-Rpg. Еретик

Идеальный мир для Социопата 4

Сапфир Олег
4. Социопат
Фантастика:
боевая фантастика
6.82
рейтинг книги
Идеальный мир для Социопата 4

Бездомыш. Предземье

Рымин Андрей Олегович
3. К Вершине
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Бездомыш. Предземье

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Игра топа

Вяч Павел
1. Игра топа
Фантастика:
фэнтези
6.86
рейтинг книги
Игра топа