How to test whether a given path is a directory or a file in C++?

Posted on In QA, Tutorial

How 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.

Eric Ma

Eric is a systems guy. Eric is interested in building high-performance and scalable distributed systems and related technologies. The views or opinions expressed here are solely Eric's own and do not necessarily represent those of any third parties.

Leave a Reply

Your email address will not be published. Required fields are marked *