3

I am reading the content of the current library with readdir, but I would like to treat only files and not directories. How do I know that I am pointing to a directory and not to a file?

kaya3
  • 47,440
  • 4
  • 68
  • 97
Debugger
  • 9,130
  • 17
  • 45
  • 53

2 Answers2

3

You can use lstat, and the S_ISDIR macro.

E.g. without error-checking:

struct stat buffer;
int status;
char path[PATH_MAX];
DIR *dir = opendir(dir_name);
... 
struct dirent *de = readdir(dir);
sprintf(path, "%s/%s", dir_name, de->d_name);
status = lstat(path, &buffer);
if(S_ISDIR(buffer.st_mode))
{
   ...
}

EDIT: Fixed to include directory in lstat path (per el.pescado). As noted by R Samuel Klatchko, you may want to take a whitelist approach (S_ISREG) instead of blacklisting types as they come up.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • You have to combine dirname and filename before passing path to lstat, eg. do sprintf(path, "%s/%s", dir_name, de->d_name); – el.pescado - нет войне Apr 16 '10 at 22:42
  • 1
    It would be a bit more robust to only process regular files entries (`S_ISREG`) rather then exclude directory entries (`S_ISDIR`). That way, if you run across another type of entry you won't accidentally process it. – R Samuel Klatchko Apr 16 '10 at 22:44
  • And just noticed something else. You need to think about whether to use `stat` or `lstat`. If you have a symlink to a real file, do you want to process it or skip it? If you want to skip it, use `lstat` so you'll know it's a symlink. If you don't care about it being a symlink and want to process it assuming it's a symlink to a regular file, use `stat`. – R Samuel Klatchko Apr 17 '10 at 06:11
0
`void DirectryNFileCount(const char * FileDir)
 {
  DIR *dir;
  int filecount;
  int dircount;
  struct dirent *direntry;
  if ((dir = opendir (FileDir)) == NULL) 
  {
   /*Error code*/
   } 
 while((direntry = readdir (dir)) != NULL)
 {
 if(direntry->d_type==DT_DIR)
 dircount++;
/*do something with directries      */
 }
 else 
 {
  filecount++;
  std::cout<<"Files Names"<<direntry->d_name<<std::endl; 
 }
 }
  std::cout<<"THIS Directory has "<<filecount<<" FILES and "<<dircount<< " DIRECTORIES";
}