简体   繁体   中英

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() . 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. Why teachers still insist on using the archaic *dir() functions in this day and age, puzzles me to no end.

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. Perhaps even print it ( path ) out, and you'll probably find the fix on your own.

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). You should use at minimum snprintf() and check its return value for overruns, or in Linux, asprintf() which allocates the resulting string dynamically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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