#include <unistd.h> #include <sys/stat.h> #include <dirent.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define PATH_LEN 256 //dir=/home/itcast/1110_linux fcn=isfile void fetchdir(const char *dir, void (*fcn)(char *)) //该函数被调用,既已被判定为目录 { char name[PATH_LEN]; struct dirent *sdp; DIR *dp; if ((dp = opendir(dir)) == NULL) { //打开目录失败 //perror("fetchdir can't open"); fprintf(stderr, "fetchdir: can't open %s ", dir); return; } while ((sdp = readdir(dp)) != NULL) { if (strcmp(sdp->d_name, ".") == 0 || strcmp(sdp->d_name, "..") == 0) { //防止出现无限递归 continue; } if (strlen(dir)+strlen(sdp->d_name)+2 > sizeof(name)) { fprintf(stderr, "fetchdir: name %s %s too long ", dir, sdp->d_name); } else { sprintf(name, "%s/%s", dir, sdp->d_name); (*fcn)(name); //函数指针回调函数 } } closedir(dp); } void isfile(char *name) //处理目录/文件 { struct stat sbuf; if (stat(name, &sbuf) == -1) { //文件名无效 fprintf(stderr, "isfile: can't access %s ", name); exit(1); } if ((sbuf.st_mode & S_IFMT) == S_IFDIR) { //判定是否为目录 fetchdir(name, isfile); //回调函数,谁是回调函数呢? } printf("%8ld %s ", sbuf.st_size, name); //不是目录,则是普通文件,直接打印文件名 } //./ls_R ~/1110_linux int main(int argc, char *argv[]) { if (argc == 1) isfile("."); else while (--argc > 0) //可一次查询多个目录 isfile(*++argv); //循环调用该函数处理各个命令行传入的目录 return 0; }