views:

1292

answers:

4

Given a path, say, /home/xyz/abc/def, I would want to determine if def is a directory or a file. Is there a way of achieving this in my C++ code?

+6  A: 

Use the stat(2) system call. You can use the S_ISREG or S_ISDIR macro on the st_mode field to see if the given path is a file or a directory. The man page tells you about all the other fields.

camh
+9  A: 

The following code uses the stat() function and the S_ISDIR ('is a directory') and S_ISREG ('is a regular file') macros to get information on the file. The rest is just error checking and enough to make a complete compilable program.

#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>

int main (int argc, char *argv[]) {
    int status;
    struct stat st_buf;

    // Ensure argument passed.

    if (argc != 2) {
        printf ("Usage: progName <fileSpec>\n");
        printf ("       where <fileSpec> is the file to check.\n");
        return 1;
    }

    // Get the status of the file system object.

    status = stat (argv[1], &st_buf);
    if (status != 0) {
        printf ("Error, errno = %d\n", errno);
        return 1;
    }

    // Tell us what it is then exit.

    if (S_ISREG (st_buf.st_mode)) {
        printf ("%s is a regular file.\n", argv[1]);
    }
    if (S_ISDIR (st_buf.st_mode)) {
        printf ("%s is a directory.\n", argv[1]);
    }

    return 0;
}

Sample runs are shown here:


pax> vi progName.c ; gcc -o progName progName.c ; ./progName
Usage: progName 
       where  is the file to check.

pax> ./progName /home
/home is a directory.

pax> ./progName .profile
.profile is a regular file.

pax> ./progName /no_such_file
Error, errno = 2
paxdiablo
your code is a bit cumbersome because of the error checking. I suggest removing this and adding some comment like "check for errors: file doesn't exist, not enough arguments". I think it'll make your answer a bit better
Nathan Fellman
I prefer it with error checking, as that is often left out of examples and people don't necessarily know how to put it back in.
Max Lybbert
I've left it in, but clarified in the text what the important bits are.
paxdiablo
+1  A: 

Alternatively you can use system() function with in built shell command "test".
system returns the exit status of command last executed

 
 string test1 = "test -e filename" ;
 if(!system(test1))
 printf("filename exists") ;

string test2 = "test -d filename" ;
 if(!system(test2))
  printf("filename is a directory") ;

 string test3 = "test -f filename" ;
 if(!system(test3))
  printf("filename is a normal file") ;

but I am afraid this would work only on linux..

Neeraj
Problematic if filename contains whitespace, I think you'd have to escape it.
Paggas
While this would work, the performance will leave a lot to be desired. Every call to system() will fork and then exec a new shell to interpret the command.
Keith Smith
+2  A: 

What about using the boost::filesystem library and its is_directory(const Path& p) ? It may take a while to get familiar with, but not so much. It probably worths the investment, and your code will not be platform specific.

Jem