简体   繁体   English

递归计算Linux C中目录中和目录下的文件数

[英]Count the number of files in, and below a directory in Linux C recursively

I write a function to count the number of files in, and below a directory (including files in the sub directory).我编写了一个函数来计算目录中和目录下的文件数(包括子目录中的文件)。 However, When I test the code on a directory with sub directory, it always report error said: "fail to open dir: No such file or directory".但是,当我在带有子目录的目录上测试代码时,它总是报告错误说:“无法打开目录:没有这样的文件或目录”。 Is there any thing I could do to make it work?有什么我可以做的事情吗?

int countfiles(char *root, bool a_flag)//a_flag decide if it including hidden file
{
    DIR *dir;
    struct dirent * ptr;
    int total = 0;
    char path[MAXPATHLEN];
    
    dir = opendir(root); //open root dirctory
    if(dir == NULL)
    {
        perror("fail to open dir");
        exit(1);
    }
    
    errno = 0;
    while((ptr = readdir(dir)) != NULL)
    {
        //read every entry in dir
        //skip ".." and "."
        if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0)
        {
            continue;
        }
       
        //If it is a directory, recurse
        if(ptr->d_type == DT_DIR)
        {
            sprintf(path,"%s%s/",root,ptr->d_name);
            //printf("%s/n",path);
            total += countfiles(path, a_flag);
        }
        
        if(ptr->d_type == DT_REG)
        {
            if(a_flag == 1){
            total++;
            }
            else if (a_flag == 0){
                if (isHidden(ptr->d_name) == 0){
                    total++;
                }
            }
        }
    }
    if(errno != 0)
    {
        printf("fail to read dir");
        exit(1);
    }
    closedir(dir);
    return total;
}

Is there anything I could make it to work?有什么我可以让它工作的吗?

Sure, lots.当然,很多。 Personally, I'd start by using the correct interface for this stuff, which in Linux and POSIXy systems would be nftw() .就我个人而言,我会首先为这些东西使用正确的接口,在 Linux 和 POSIXy 系统中应该是nftw() This would lead to a program that was not only shorter and more effective, but would not as easily get confused if someone renames a directory or file in the tree being scanned at the same time.这将导致程序不仅更短、更有效,而且如果有人重命名同时扫描的树中的目录或文件,则不会那么容易混淆。

Programmers almost never implement opendir()/readdir()/closedir() as robustly and as efficiently as nftw() , scandir() , glob() , or the fts family of functions do.程序员几乎从来没有像nftw()scandir()glob()fts 系列函数那样健壮和高效地实现 opendir()/readdir()/closedir() 。 Why teachers still insist on using the archaic *dir() functions in this day and age, puzzles me to no end.为什么老师们在这个时代仍然坚持使用古老的 *dir() 函数,这让我困惑不已。

If you have to use the *dir functions because your teacher does not know POSIX and wants you to use interfaces you should not use in real life, then look at how you construct the path to the new directory: the sprintf() line.如果你因为你的老师不知道 POSIX 而你必须使用 *dir 函数并且希望你使用你在现实生活中不应该使用的接口,那么看看你如何构建新目录的路径:sprintf() 行。 Perhaps even print it ( path ) out, and you'll probably find the fix on your own.也许甚至将它打印出来( path ),您可能会自己找到修复程序。

Even then, sprintf() is not something that is allowed in real life programs (because it will cause a silent buffer overrun when the arguments are longer than expected; and that CAN happen in Linux, because there actually isn't a fixed limit on the length of a path).即便如此, sprintf()在现实生活中也不是允许的(因为当参数比预期的长时,它会导致静默缓冲区溢出;而在 Linux 中可能会发生这种情况,因为实际上没有固定的限制)路径的长度)。 You should use at minimum snprintf() and check its return value for overruns, or in Linux, asprintf() which allocates the resulting string dynamically.您应该至少使用snprintf()并检查其返回值是否有溢出,或者在 Linux 中使用动态分配结果字符串的asprintf()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM