深度递归遍历文件夹中所有文件

 #include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <dirent.h>
#include <sys/stat.h>

#define RET_ERROR (-1)
#define RET_OKAY (0)

#define DIRLIST_RECURSIVE

#define ISSLASH(C) ((C) == '/')

inline long dirent_buf_size(DIR *dirp)
{
    long name_max, len;

    name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
    if (name_max == -1) /* Limit not defined, or error */
        name_max = 255; /* Take a guess */
    len = offsetof(struct dirent, d_name) + name_max + 1;

    return len;
}

inline int is_dot_or_dotdot(char *pathname)
{
    if (pathname[0] == '.') {
        char sep = pathname[(pathname[1] == '.') + 1];
        return !sep;
    } else
        return 0;
}

inline int is_directory(char *pathname)
{
    struct stat stat_buf;

    if (lstat(pathname, &stat_buf) == -1)
        perror(":: lstat ");
    else {
        if (S_ISDIR(stat_buf.st_mode))
            return 1;
    }

    return 0;
}

/* scandir (optional, sort) files under directory "pathname" */
int _scandir(char *pathname)
{
    DIR *dirp;
    struct dirent **namelist;
    char *currentpath;
    long max_pathname, namelen, orig_offset;
    int count;

    dirp = opendir(pathname);
    if (dirp == NULL) {
        perror(":: opendir ");
        return RET_ERROR;
    }

    max_pathname = dirent_buf_size(dirp);

    namelen = strlen(pathname) + max_pathname + 1;

    currentpath = malloc(namelen);
    if (currentpath == NULL) {
        perror(":: malloc ");

        closedir(dirp);
        return RET_ERROR;
    }
    memset(currentpath, 0, namelen);

    orig_offset = sprintf(currentpath, "%s/", pathname);

    // count = scandir(currentpath, &namelist, NULL, alphasort);
    count = scandir(currentpath, &namelist, NULL, NULL);
    if (count == -1)
        perror(":: scandir ");
    else {
        while (count--) {
            if (is_dot_or_dotdot(namelist[count]->d_name)) {
                continue;
                free(namelist[count]);
            }

            sprintf(currentpath + orig_offset, "%s", namelist[count]->d_name);
            printf("%s\n", currentpath);

            free(namelist[count]);

#ifdef DIRLIST_RECURSIVE
            if (is_directory(currentpath))
                _scandir(currentpath);
#endif
        }
        free(namelist);
    }

    closedir(dirp);
    free(currentpath);

    return RET_OKAY;
}

/* reentrant version */
int dirlist_r(char *pathname)
{
    DIR *dirp;
    struct dirent *dt, *entry;
    long max_pathname, namelen, orig_offset;
    char *currentpath;

    dirp = opendir(pathname);
    if (dirp == NULL) {
        perror(":: opendir ");
        return RET_ERROR;
    }

    max_pathname = dirent_buf_size(dirp);

    entry = malloc(max_pathname);
    if (entry == NULL) {
        perror(":: malloc ");
        closedir(dirp);
        return RET_ERROR;
    }

    namelen = strlen(pathname) + max_pathname + 1;

    currentpath = malloc(namelen);
    if (currentpath == NULL) {
        perror(":: malloc ");

        free(entry);
        closedir(dirp);
        return RET_ERROR;
    }
    memset(currentpath, 0, namelen);

    orig_offset = sprintf(currentpath, "%s/", pathname);

    while ((readdir_r(dirp, entry, &dt) == 0) && (dt != NULL)) {
        /* hide . & .. */
        if (is_dot_or_dotdot(dt->d_name))
            continue;

        sprintf(currentpath + orig_offset, "%s", dt->d_name);

        printf("%s\n", currentpath);

#ifdef DIRLIST_RECURSIVE
        if (is_directory(currentpath))
            dirlist_r(currentpath);
#endif
    }

    free(entry);
    free(currentpath);
    closedir(dirp);

    return RET_OKAY;
}

int dirlist(char *pathname)
{
    DIR *dirp;
    struct dirent *dt;
    char *currentpath;
    long max_pathname, namelen, orig_offset;
    int olderrno;

    dirp = opendir(pathname);
    if (dirp == NULL) {
        perror(":: opendir ");
        return RET_ERROR;
    }

    max_pathname = dirent_buf_size(dirp);

    namelen = strlen(pathname) + max_pathname + 1;

    currentpath = malloc(namelen);
    if (currentpath == NULL) {
        perror(":: malloc ");

        closedir(dirp);
        return RET_ERROR;
    }
    memset(currentpath, 0, namelen);

    orig_offset = sprintf(currentpath, "%s/", pathname);

    for (;;) {
        olderrno = errno;

        dt = readdir(dirp);
        if (dt == NULL) {
            /* error detected when errno changed with readdir return NULL. */
            if (errno != olderrno)
                perror(":: readdir ");
            /* else, end of stream reached */
            break;
        }

        /* hide . & .. */
        if (is_dot_or_dotdot(dt->d_name))
            continue;

        sprintf(currentpath + orig_offset, "%s", dt->d_name);

        printf("%s\n", currentpath);

#ifdef DIRLIST_RECURSIVE
        if (is_directory(currentpath))
            dirlist(currentpath);
#endif
    }

    free(currentpath);
    closedir(dirp);

    return RET_OKAY;
}

int main(int argc, char **argv)
{
    if (argc > 1 && argv[1]) {
        dirlist_r(argv[1]);
        // dirlist(argv[1]);
        // _scandir(argv[1]);
    } else {
        dirlist_r(".");
        // dirlist(".");
        // _scandir(".");
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值