How to test whether a given path is a directory or a file in C++?
Posted on In QA, TutorialHow to test whether a given path is a directory or a file in C++? For example,
pathtype("/") --> "a dir"
pathtype("/tmp/file.txt") --> "a file" # if there is a file file.txt
pathtype("/tmp/dir.txt") --> "a dir" # if there is a dir named dir.txt
The type of a file/dir can be found out using lstat()
and the macros on Linux.
int lstat(const char *pathname, struct stat *statbuf);
lstat
return information about a file, in the buffer pointed to by statbuf. If pathname is a symbolic link, lstat()
returns information about the link itself, not the file that it refers to.
The following macros test whether a file is of the specified type. The value m supplied to the macros is the value of st_mode from a stat structure. The macro shall evaluate to a non-zero value if the test is true; 0 if the test is false.
S_ISDIR(m) Test for a directory.
S_ISREG(m) Test for a regular file.
An example C++ program is as follows.
#include <sys/stat.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
int main (int argc, char *argv[])
{
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " path\n";
return 1;
}
std::string path(argv[1]);
struct stat s;
if ( lstat(path.c_str(), &s) == 0 ) {
if ( S_ISDIR(s.st_mode) ) {
// it's a directory
std::cout << path << " is a dir.\n";
} else if (S_ISREG(s.st_mode)) {
// it's a file
std::cout << path << " is a file.\n";
} else if (S_ISLNK(s.st_mode)) {
// it's a symlink
std::cout << path << " is a symbolic link.\n";
} else {
//something else
std::cout << path << " type is not recognized by this program.\n";
}
} else {
//error
std::cerr << "stat() return !0 value\n";
return 1;
}
return 0;
}
Examples results.
$ touch /tmp/file.txt
$ ./pathtype /tmp/file.txt
/tmp/file.txt is a file.
$ mkdir /tmp/dir.txt
$ ./pathtype /tmp/dir.txt
/tmp/dir.txt is a dir.