Discerning between files and folders on a shared drive under Linux [duplicate]
-
01-07-2021 - |
Question
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.
Solution
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
.
OTHER TIPS
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.
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.
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);
}
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;
}
}