如何在 Linux 上的 C 中查找目录及其子目录中的文件?

Posted

技术标签:

【中文标题】如何在 Linux 上的 C 中查找目录及其子目录中的文件?【英文标题】:How to find a file in a directory and its subdirectories in C on Linux? 【发布时间】:2021-08-06 18:12:15 【问题描述】:

我想编写一个给定文件名的程序,在当前目录及其子目录中搜索该文件。应该打印包含该文件的子目录的名称。

但我的代码只打印子目录。

#include <dirent.h>
#include <stdio.h>
#include <string.h>

void listDir(char *path, char *name)

    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir(path)) != NULL) 
        while (( ent = readdir(dir)) != NULL) 
            if (ent->d_type == DT_REG && name == ent->d_name) 
                printf("%s\n", ent->d_name);
            

            if (ent->d_type == DT_DIR && strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) 
                printf("%s\n", ent->d_name);
                listDir("/home/dir1/ent->d_name", name);
            
        
        closedir(dir);
    


void main()

    listDir("/home/dir1", "file1");

【问题讨论】:

strcmp(ent-$ 此处似乎缺少某些内容。 man nftw .... @MikeCAT 谢谢 为什么不使用nftw()、scandir()或glob()呢?我真的希望新的 POSIX C 程序员被教导不要使用 opendir()/readdir()/closedir(),而是使用适当的 POSIX 接口:nftw()、scandir()、glob() 和 wordexp()。跨度> 【参考方案1】:

您要么需要跟踪完整路径,要么深入每个目录。 (如果您正在查看foo/bar/baz,那么如果您在***目录中,opendir("baz") 将失败)。比如:

#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>

void
listDir(char* path, const char *name)

        DIR* dir;
        struct dirent *ent;

        char *end = strrchr(path, '\0');

        if( (dir = opendir(path)) == NULL )
                perror(path);
                return;
         else while( (ent = readdir(dir)) != NULL )
                if( ent->d_type == DT_DIR && strcmp(ent->d_name, ".")
                                 && strcmp(ent->d_name, "..") )
                
                        snprintf(end, PATH_MAX - (end - path), "/%s",
                                ent->d_name);
                        listDir(path, name);
                        *end = '\0';
                 else if( !strcmp(ent->d_name, name) )
                        printf("%s\n", path);
                
        
        closedir(dir);


int
main(int argc, char **argv)

        char path[PATH_MAX];
        char *defaults[] = NULL, NULL, ".", NULL;
        if( argc < 2 )
                printf("usage: %s name [path...]", argv[0]);
                return EXIT_SUCCESS;
        
        const char *name = argv[1];
        if( argc < 3 )
                argv = defaults;
        
        for( argv += 2; *argv; argv += 1 )
                /* getcwd(fullpath, PATH_MAX); */
                snprintf(path, PATH_MAX, "%s", *argv);
                listDir(path, name);
        
        return 0;

【讨论】:

strrchr(path, '\0'); 是一种计算字符串长度的创造性方法...【参考方案2】:

您的代码存在多个问题:

比较name == ent-&gt;d_name不适用于字符串指针,您应该使用!strcmp(name, ent-&gt;d_name)

listDir("/home/dir1/ent-&gt;d_name", name); 不会神奇地 连接字符串。您应该使用 snprintfasprintf(在 linux 和 BSD 系统上)来构造子目录名称。

这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void listDir(const char *path, const char *name) 
    DIR *dir;
    struct dirent *ent;

    if ((dir = opendir(path)) != NULL) 
        while ((ent = readdir(dir)) != NULL) 
            if (ent->d_type == DT_REG && !strcmp(name, ent->d_name)) 
                printf("%s\n", path);
            
            if (ent->d_type == DT_DIR && strcmp(ent->d_name, ".")
                                      && strcmp(ent->d_name, "..")) 
                char *subdir;
                size_t len = strlen(path);
                const char *sep = "/";
                if (len && path[len - 1] == '/')
                    sep++;
                if (asprintf(&subdir, "%s%s%s", path, sep, ent->d_name) > 0) 
                    listDir(subdir, name);
                    free(subdir);
                
            
        
        closedir(dir);
    


int main(int argc, char *argv[]) 
    if (argc == 3) 
        listDir(argv[1], argv[2]);
     else 
        fprintf(stderr, "usage: %s FILE DIR\n", argv[0]);
    
    return 0;

【讨论】:

以上是关于如何在 Linux 上的 C 中查找目录及其子目录中的文件?的主要内容,如果未能解决你的问题,请参考以下文章

Linux上的find命令详解

Linux系统下查找安装包所在目录

Linux系统下查找安装包所在目录

如何在使用查找时列出没有绝对路径的目录中的所有文件及其文件大小

linux 下怎样修改一个目录及其子目录下的所有文件的 修改时间 ???

linux小命令