linux 列出目录下的所有文件和目录

33 篇文章 1 订阅

下面的代码是列出指定目录下的所有文件和目录,且支持递归搜索算法。


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

/**
 * List all the files and directories under the specified directory, recursively.
 *
 */
void list_files(const char* directory, char*** filenames, int* file_count, int* array_size)
{
    DIR* dir;
    struct dirent* de;
    char file_name[FILENAME_MAX];
    struct stat st;
    
    dir = opendir(directory);
    if (NULL == dir) {
        printf("ERROR: open failed: %s(%s)\n", directory, strerror(errno));
        return;
    }
    
    bool end_with_slash = ('/' == directory[strlen(directory) - 1]);
    bool is_dir;
    while ((de = readdir(dir)) != 0) {
        strcpy(file_name, directory);
        if (!end_with_slash) strcat(file_name, "/");
        strcat(file_name, de->d_name);
        
        printf("de->d_name: %s\n", de->d_name);
        if ('.' == de->d_name[0]) {
            if (0 == de->d_name[1]) continue; // .
            if (('.' == de->d_name[1]) && (0 == de->d_name[2])) continue; // ..
        }
        
        if (stat(file_name, &st) != 0) {
            printf("stat failed: %s, %s\n", file_name, strerror(errno));
            continue;
        }
        
        if ((is_dir = S_ISDIR(st.st_mode)) || S_ISREG(st.st_mode)) {
            if (*file_count > *array_size) {
                *array_size = (*array_size) * 2;
                *filenames = (char**)realloc(*filenames, (*array_size) * sizeof(char*));
            }
            
            (*filenames)[(*file_count)++] = strdup(file_name);
            
            if (is_dir) {
                list_files(file_name, filenames, file_count, array_size);
            }
        } else {
            printf("Other files: %s\n", file_name);
        }
    }
    
    closedir(dir);
}

static void test(const char* directory)
{
    char** filenames;
    int file_count = 0;
    int array_size = 16;
    
    filenames = (char**)malloc(array_size * sizeof(char*));
    if (NULL == filenames) {
        printf("No memory.\n");
        return;
    }
    
    list_files(directory, &filenames, &file_count, &array_size);
    
    printf("All files:\n");
    for (int i = 0; i < file_count; i++) {
        printf("%s\n", filenames[i]);
        free(filenames[i]);
        filenames[i] = NULL;
    }
    
    free(filenames);
}

int main(int argc, const char* argv[])
{
    if (argc != 2) {
        printf("Usage: %s dir_name\n", argv[0]);
        return 1;
    }

    test(argv[1]);
    
    return 0;
}

 目录结构 示例: 

flying-bird@flyingbird:~/examples/cpp/list_files/test$ ll . a/ b/
.:
total 24
drwxrwxr-x 4 flying-bird flying-bird 4096  7月 27 20:31 ./
drwxrwxr-x 3 flying-bird flying-bird 4096  7月 27 20:31 ../
drwxrwxr-x 2 flying-bird flying-bird 4096  7月 27 20:31 a/
drwxrwxr-x 2 flying-bird flying-bird 4096  7月 27 20:31 b/
-rw-rw-r-- 1 flying-bird flying-bird    6  7月 27 20:31 first.txt
-rw-rw-r-- 1 flying-bird flying-bird    7  7月 27 20:31 second.txt

a/:
total 16
drwxrwxr-x 2 flying-bird flying-bird 4096  7月 27 20:31 ./
drwxrwxr-x 4 flying-bird flying-bird 4096  7月 27 20:31 ../
-rw-rw-r-- 1 flying-bird flying-bird    6  7月 27 20:31 first.txt
-rw-rw-r-- 1 flying-bird flying-bird    7  7月 27 20:31 second.txt

b/:
total 16
drwxrwxr-x 2 flying-bird flying-bird 4096  7月 27 20:31 ./
drwxrwxr-x 4 flying-bird flying-bird 4096  7月 27 20:31 ../
-rw-rw-r-- 1 flying-bird flying-bird    6  7月 27 20:31 first.txt
-rw-rw-r-- 1 flying-bird flying-bird    7  7月 27 20:31 second.txt
flying-bird@flyingbird:~/examples/cpp/list_files/test$ 


再增加一个symlink:

flying-bird@flyingbird:~/examples/cpp/list_files/test$ ln -s test test
flying-bird@flyingbird:~/examples/cpp/list_files/test$ ll
total 24
drwxrwxr-x 4 flying-bird flying-bird 4096  7月 27 20:43 ./
drwxrwxr-x 3 flying-bird flying-bird 4096  7月 27 20:38 ../
drwxrwxr-x 2 flying-bird flying-bird 4096  7月 27 20:31 a/
drwxrwxr-x 2 flying-bird flying-bird 4096  7月 27 20:31 b/
-rw-rw-r-- 1 flying-bird flying-bird    6  7月 27 20:31 first.txt
-rw-rw-r-- 1 flying-bird flying-bird    7  7月 27 20:31 second.txt
lrwxrwxrwx 1 flying-bird flying-bird    4  7月 27 20:43 test -> test
flying-bird@flyingbird:~/examples/cpp/list_files/test$


没有symlink时的运行示例:

flying-bird@flyingbird:~/examples/cpp/list_files$ ./a.out ./test/
de->d_name: b
de->d_name: first.txt
de->d_name: second.txt
de->d_name: .
de->d_name: ..
de->d_name: first.txt
de->d_name: second.txt
de->d_name: .
de->d_name: ..
de->d_name: a
de->d_name: first.txt
de->d_name: second.txt
de->d_name: .
de->d_name: ..
All files:
./test/b
./test/b/first.txt
./test/b/second.txt
./test/first.txt
./test/second.txt
./test/a
./test/a/first.txt
./test/a/second.txt
flying-bird@flyingbird:~/examples/cpp/list_files$ 

增加symlink的运行示例:

flying-bird@flyingbird:~/examples/cpp/list_files$ ./a.out test/
de->d_name: b
de->d_name: first.txt
de->d_name: second.txt
de->d_name: .
de->d_name: ..
de->d_name: first.txt
de->d_name: second.txt
de->d_name: .
de->d_name: test
stat failed: test/test, Too many levels of symbolic links
de->d_name: ..
de->d_name: a
de->d_name: first.txt
de->d_name: second.txt
de->d_name: .
de->d_name: ..
All files:
test/b
test/b/first.txt
test/b/second.txt
test/first.txt
test/second.txt
test/a
test/a/first.txt
test/a/second.txt
flying-bird@flyingbird:~/examples/cpp/list_files$ 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值