In depth: Linux traverses all files under a folder

  • 2020-04-02 01:04:36
  • OfStack

Linux C traverses directories and their subdirectories

#include <stdio.h>  
#include <string.h> 
#include <stdlib.h>  
#include <dirent.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <sys/types.h> 
using namespace std;
void listDir(char *path)  
{  
        DIR              *pDir ;  
        struct dirent    *ent  ;  
        int               i=0  ;  
        char              childpath[512];  

        pDir=opendir(path);  
        memset(childpath,0,sizeof(childpath));  

  
        while((ent=readdir(pDir))!=NULL)  
        {  

                if(ent->d_type & DT_DIR)  
                {  

                        if(strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)  
                                continue;  

                        sprintf(childpath,"%s/%s",path,ent->d_name);  
                        printf("path:%s/n",childpath);  

                        listDir(childpath);  

                }  
else
{
cout<<ent->d_name<<endl;
}
        }  

}  

int main(int argc,char *argv[])  
{  
        listDir(argv[1]);  
        return 0;  
}

Linux C: traverses the output of all files in the specified directory
Under Linux Opendir (), readdir(), and closedir() These three functions are primarily used to traverse directories. Before using these three functions The following two header files must be included:
# include < Sys/types. H >
# include < Dirent. H >
The opendir function is prototyped as:
DIR * opendir (const char * name);
It returns a DIR* type, which is a handle, and you don't have to worry about its internal structure, just know that the handle is the argument to be passed to the readdir() function later.
The prototype of the readdir function is:
Struct dirent * readdir (DIR * DIR);
The argument is the handle returned by the opendir function, and the return value of the function is of type struct dirent*.

struct dirent {
               ino_t          d_ino;       
                off_t          d_off;       
                unsigned short d_reclen;    
                unsigned char  d_type;      
                char           d_name[256]; 
};

The d_name of this structure is the name of the file, the file in this case is a regular file, a directory file, etc. In the Linux mind, everything is a file.
The prototype of the closedir function is:
Int closedir (DIR * DIR);
This function need not say more, generally have open, related to (close), such structure can often be seen, such as fopen, fclose and so on.
That's all for the three functions, so let's do an example:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SearchDir. C * * * * * * * * * * * * * * * * * * * * * * * * * * * *

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
char filename[256][256];
int len = 0;
int trave_dir(char* path, int depth)
{
    DIR *d; //Declare a handle
    struct dirent *file; //The return value of the readdir function is stored in this structure
    struct stat sb;    

    if(!(d = opendir(path)))
    {
        printf("error opendir %s!!!n",path);
        return -1;
    }
    while((file = readdir(d)) != NULL)
    {
        //Put the current directory.., the next directory.. And hidden files are removed to avoid dead loop traversal directory
        if(strncmp(file->d_name, ".", 1) == 0)
            continue;
        strcpy(filename[len++], file->d_name); //Save the traversed file name
        //To determine whether the file is a directory or not, and whether it has been searched for three layers, here I define only three layers of directory, too deep to search, save too many files
        if(stat(file->d_name, &sb) >= 0 && S_ISDIR(sb.st_mode) && depth <= 3)
        {
            trave_dir(file->d_name, depth + 1);
        }
    }
    closedir(d);
    return 0;
}
int main()
{
    int depth = 1;
    int i;
    trave_dir("/usr/keygoe/ini/", depth);
    for(i = 0; i < len; i++)
    {
        printf("%st", filename[i]);
    }
    printf("n");
    return 0;
}

C traverses folders under Linux
Learned LINUX using C language traversal folder, some tips
Several members of struct dirent:
D_type: 4 represents a directory and 8 represents a file
D_reclen: 16 represents a subdirectory or file, and 24 represents a non-subdirectory
In my own experiments, I found that d_reclen: 16 represents subdirectories or hidden files beginning with., 24 represents plain text files, 28 is binary, and so on
D_name: The name of a directory or file
The specific code is as follows, for reference only

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
void List(char *path)
{
     struct dirent* ent = NULL;
     DIR *pDir;
     pDir=opendir(path);
     while (NULL != (ent=readdir(pDir)))
     {
         if (ent->d_reclen==24)
         {
             if (ent->d_type==8)
             {
                 printf(" Common file :%sn", ent->d_name);
             }
             else
             {
                 printf(" Subdirectories: %sn",ent->d_name);
                 List(ent->d_name);
                 printf(" return %sn",ent->d_name);
             }
         }
     }
}
int main(int argc, char *argv[])
{
      List(argv[1]);
      return 0;
}

After the above function is modified:

void List(char *path)
{
     printf(" Path for [%s]n", path);

     struct dirent* ent = NULL;
     DIR *pDir;
     pDir=opendir(path);
     //D_reclen: 16 for subdirectories or hidden files beginning with., 24 for plain text files,28 for binaries, and so on...
     while (NULL != (ent=readdir(pDir)))
     {
         printf("reclen=%d    type=%dt", ent->d_reclen, ent->d_type);
         if (ent->d_reclen==24)
         {    
             //D_type: 4 is represented as a directory and 8 as a file
             if (ent->d_type==8)
             {
                 printf(" Common file [%s]n", ent->d_name);
             }
         }
         else if(ent->d_reclen==16)
         {
             printf("[.] A subdirectory or hidden file at the beginning [%s]n",ent->d_name);
         }
         else
         {
             printf(" Other documents [%s]n", ent->d_name);
         }
     }
}


#include   <stdio.h>   
#include   <dirent.h>   
#include   <sys/types.h>   
#include   <sys/stat.h>   

void dir_scan(char   *path,   char   *file);   
int count = 0;   

int main(int   argc,   char   *argv[])   
{   
                   struct   stat   s;   

                   if(argc   !=   2){   
                                   printf("one   direction   requriedn");   
                                   exit(1);   
                   }   
                   if(lstat(argv[1],   &s)   <   0){   
                                   printf("lstat   errorn");   
                                   exit(2);   
                   }   
                  //Determines if a path is a directory
                   if(!S_ISDIR(s.st_mode)){   
                                   printf("%s   is   not   a   direction   namen",   argv[1]);   
                                   exit(3);   
                   }   

                   dir_scan("",   argv[1]);   

                   printf("total:   %d   filesn",   count);   

                   exit(0);   
}   

void   dir_scan(char   *path,   char   *file)   
{   
                   struct   stat   s;   
                   DIR           *dir;   
                   struct   dirent   *dt;   
                   char   dirname[50];   

                   memset(dirname,   0,   50*sizeof(char));   
                   strcpy(dirname,   path);   

                   if(lstat(file,   &s)   <   0){   
                                   printf("lstat   errorn");   
                   }   

                   if(S_ISDIR(s.st_mode)){   
                                   strcpy(dirname+strlen(dirname),   file);   
                                   strcpy(dirname+strlen(dirname),   "/");   
                                   if((dir   =   opendir(file))   ==   NULL){   
                                                   printf("opendir   %s/%s   errorn");   
                                                   exit(4);   
                                   }   
                                   if(chdir(file)   <   0)   {   
                                                   printf("chdir   errorn");   
                                                   exit(5);   
                                   }   
                                   while((dt   =   readdir(dir))   !=   NULL){   
                                                   if(dt->d_name[0]   ==   '.'){   
                                                                   continue;   
                                                   }   

                                                   dir_scan(dirname,   dt->d_name);   
                                   }   
                                   if(chdir("..")   <   0){   
                                                   printf("chdir   errorn");   
                                                   exit(6);   
                                   }   
                   }else{   
                                   printf("%s%sn",   dirname,   file);   
                                   count++;   
                   }   
}

How to get the number of files in a directory under Linux c.

int main(int argc, char **argv)
{    
      DIR  * pdir;
     struct dirent * pdirent;
     struct stat f_ftime;
     int fcnt;
      pdir=opendir("./");
     if(pdir==NULL)
     {      return(-1);    }
      fcnt=0;
     for(pdirent=readdir(pdir);pdirent!=NULL;pdirent=readdir(pdir))
     {
       if(strcmp(pdirent->d_name,".")==0||strcmp(pdirent->d_name,"..")==0) continue;
       if(stat(pdirent->d_name,&f_ftime)!=0) return -1 ;
       if(S_ISDIR(f_ftime.st_mode)) continue; 
        fcnt++;  
       printf(" file :%sn",pdirent->d_name);
     }
     printf(" The total number of files %dn",fcnt);
      closedir(pdir);
     return 0; 
}
#include <unistd.h>  
#include <stdio.h>  
#include <dirent.h>  
#include <string.h>  
#include <sys/stat.h>  

void printdir(char *dir, int depth) 
{ 
          DIR *dp; 
          struct dirent *entry; 
          struct stat statbuf; 

          if((dp = opendir(dir)) == NULL) { 
                      fprintf(stderr, "cannot open directory: %sn ", dir); 
                      return; 
          } 
          chdir(dir); 
          while((entry = readdir(dp)) != NULL) { 
                      lstat(entry-> d_name,&statbuf); 
                      if(S_ISDIR(statbuf.st_mode)) { 
                                  /**/ 
                                  if(strcmp( ". ",entry-> d_name) == 0 || 
                                              strcmp( ".. ",entry-> d_name) == 0) 
                                              continue; 
                                  printf( "%*s%s/n ",depth, " ",entry-> d_name); 
                                  /**/ 
                                  printdir(entry-> d_name,depth+4); 
                      } 
                      else printf( "%*s%sn ",depth, " ",entry-> d_name); 
          } 
          chdir( ".. "); 
          closedir(dp); 
} 

/**/ 

int main(int argc, char* argv[]) 
{ 
          char *topdir, pwd[2]= ". "; 
          if (argc != 2) 
                      topdir=pwd; 
          else 
                      topdir=argv[1]; 

          printf( "Directory scan of %sn ",topdir); 
          printdir(topdir,0); 
          printf( "done.n "); 

          exit(0); 
} 


Related articles: