Язык программирования Си



         

Пример. Печать каталогов - часть 3


#define S_IFMT 0160000 /* тип файла */ #define S_IFDIR 0040000 /* каталог */ #define S_IFCHR 0020000 /* символьно-ориентированный */ #define S_IFBLK 0060000 /* блочно-ориентированный */ #define S_IFREG 0100000 /* обычный */

Теперь мы готовы приступить к написанию программы fsize. Если режимные биты (st_mode), полученные от stat, указывают, что файл не является каталогом, то можно взять его размер (st_size) и напечатать. Однако если файл - каталог, то мы должны обработать все его файлы, каждый из которых в свою очередь может быть каталогом. Обработка каталога - процесс рекурсивный.

Программа main просматривает параметры командной строки, передавая каждый аргумент функции fsize.

#include <stdio.h> #include <string.h> #include "syscalls.h" #include <fcntl.h> /* флажки чтения и записи */ #include <sys/types.h> /* определения типов */ #include <sys/stat.h> /* структура, возвращаемая stat */ #include "dirent.h"

void fsize(char *);

/* печатает размер файлов */ main(int argc, char **argv) { if (argc == 1)/* по умолчанию берется текущий каталог */ fsize("."); else while (--argc > 0) fsize(*++argv); return 0; }

Функция fsize печатает размер файла. Однако, если файл - каталог, она сначала вызывает dirwalk, чтобы обработать все его файлы. Обратите внимание на то, как используются имена флажков S_IFMT и S_IFDIR из <sys/stat.h> при проверке, является ли файл каталогом. Здесь нужны скобки, поскольку приоритет оператора & ниже приоритета оператора ==.

int stat(char *, struct stat *); void dirwalk(char *, void (*fcn)(char *));

/* fsize: печатает размер файла "name" */ void fsize(char *name) { struct stat stbuf;

if (stat(name, &stbuf) == -1) { fprintf(stderr, "fsize: нет доступа к %s\n", name); return; } if ((stbuf.st_mode & S_IFMT) == S_IFDIR) dirwalk(name, fsize); printf("%8ld%s\n", stbuf.st_size, name); }

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




Содержание  Назад  Вперед