2

I am trying to list all the files in a certain directory on a shared drive using the following code:

#include <iostream>
#include <string>

#include "dirent.h"

int main ()
{
    DIR *directoryHandle = opendir("./temp/");
    if (NULL != directoryHandle)
    {
        dirent *entry = readdir(directoryHandle);
        while (NULL != entry)
        {
            //skip directories and select only files (hopefully)
            if ((DT_DIR != entry->d_type) && (DT_REG == entry->d_type || DT_UNKNOWN == entry->d_type))
            {
                std::cout << "Name: " << entry->d_name << " Type:" << std::to_string(entry->d_type) << std::endl;
            }

            //go to next entry
            entry = readdir(directoryHandle);
        }
        closedir(directoryHandle);
    }

    return 0;
}

The problem is that entry->d_type contains DT_UNKNOWN for directories as well as for files in the ./temp/ directory.

Is there any (reliable) linux-specific way to try and read each entry and determine if it's a file or directory?

The output of cat /etc/SuSE-release is:

SUSE Linux Enterprise Desktop 11 (x86_64) VERSION = 11 PATCHLEVEL = 1

The Linux version is: 2.6.32.59-0.7-default

Still, I expect this code to work on other platforms as well.

Mihai Todor
  • 8,014
  • 9
  • 49
  • 86
  • 2
    What does "shared drive" mean here? smb,nfs, sshfs etc.? oh and you are confusing the kernel version with the distro version. – PlasmaHH Sep 11 '12 at 15:01
  • Ups... I'm not that experienced with the Linux system. The output of `df -T` indicates `nfs4` for that drive. – Mihai Todor Sep 11 '12 at 15:04

5 Answers5

6

Use stat. You'll get a struct stat with an st_mode field, and macros S_ISDIR/S_ISREG:

isDirectory = S_ISDIR(statBuf.st_mode);
isFile = S_ISREG(statBuf.st_mode);

See man 2 stat. Include sys/stat.h.

pb2q
  • 58,613
  • 19
  • 146
  • 147
5

If you are getting DT_UNKNOWN you're going to have to go ahead and call lstat() and inspect the st_mode field to determine if this is a file, directory, or symlink. If you don't care about symlinks, use stat() instead.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
3

There's the boost filesystem library that has a command is_directory. Using such a library would certainly make the code work on other platforms as well but I'm not sure if it will work for your specific problem.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
denahiro
  • 1,211
  • 7
  • 10
2

Give this a try. It list files in a directory minus the folders :

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

DIR           *d;
struct dirent *dir;
struct stat s;
d = opendir("./temp/");

if (d)
{
  while ((dir = readdir(d)))
  {
    if (stat(dir->d_name,&s) != 0) {
        /* is this a regular file? */
        if ((s.st_mode & S_IFMT) == S_IFREG)
            printf("%s\n", dir->d_name);

    }
  }
  closedir(d);
}
Software_Designer
  • 8,490
  • 3
  • 24
  • 28
-2
unsigned char isFolder =0x4;
DIR Dir;
struct dirent *DirEntry;
Dir = opendir("c:/test/")

while(Dir=readdir(Dir))
{
    cout << DirEntry->d_name;
    if ( DirEntry->d_type == isFolder)
    {
    cout <<"Found a Directory : " << DirEntry->d_name << endl;
    } 
}