6

When I do:

FILE * fp = fopen("filename", "r");`  

How can I know the file pointer fp points to a file or a directory? Because I think both cases the fp won't be null. What can I do?

The environment is UNIX.

alk
  • 69,737
  • 10
  • 105
  • 255
lkkeepmoving
  • 2,323
  • 5
  • 25
  • 31

3 Answers3

3

i've found this near by:

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

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

    status = stat ("your path", &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]);
    }
}
No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
2

You could use fileno() to get the file discriptor for the already opened file, and then use fstat() on the file descriptor to have a struct stat returned.

It's member st_mode carries info on the file.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main()
{
  FILE * pf = fopen("filename", "r");
  if (NULL == pf)
  {
    perror("fopen() failed");
    exit(1);
  }

  {
    int fd = fileno(pf);
    struct stat ss = {0};

    if (-1 == fstat(fd, &ss))
    {
      perror("fstat() failed");
      exit(1);
    }

    if (S_ISREG (ss.st_mode))  
    {
      printf ("Is's a file.\n");
    }
    else if (S_ISDIR (ss.st_mode)) 
    {
     printf ("It's a directory.\n");
    }
  }

  return 0;
}
alk
  • 69,737
  • 10
  • 105
  • 255
  • If we decide to use `stat` family, why not use them directly? why an extra call to `fileno`? – P.P Sep 10 '13 at 06:15
  • @KingsIndian: Because the question is asking for it: "*... know the file pointer fp points to a ...*". – alk Sep 10 '13 at 06:16
  • That *I have only fp, not filename* is applicable only if there's such a restriction (e.g. An API passes only fp, not filename). Otherwise, there's always a filename available somewhere. In OP's example, he does have filename. In fact, we can get two of `fp`, `fd`, `filename` if we have one of them (This is admittedly equivalent to what you have). But I doubt there's such a limitation in the question. – P.P Sep 10 '13 at 06:51
0

On Windows, Call GetFileAttributes, and check for the FILE_ATTRIBUTE_DIRECTORY attribute.

Check this and this.

Community
  • 1
  • 1
manimatters
  • 424
  • 3
  • 11