10

Possible Duplicate:
What’s the best way to check if a file exists in C? (cross platform)

i would like to check if a file exists or not. I changed the permissions of my testfile to "chmod -r somefile". However now it says that the file does not exist even though it does exist.

So i assume if i dont have read permissions i cannot open the file with "fopen r". But that would mean that there is no easy way to tell if a file exists or cannot be read/written?

Or am i missing something? Any help would be great.

Thanks!

int doesFileExist(const char* filename)
{
  FILE* fptr = fopen(filename, "r");
  if (fptr != NULL)
  {
    fclose(fptr);
    printf("File exists\n");
    return 1;
  }
  printf("File doesnt exist\n");
  return 0;
}

Update: Thanks guys for these great links and explanations!

Community
  • 1
  • 1
Susan
  • 301
  • 1
  • 5
  • 17
  • 1
    Um.. have you checked `errno`? EDIT: try this to get some error message: `printf("File doesnt exist: %s\n",strerror(errno));` don't forget to include `errno.h` header. – Jack Dec 19 '12 at 04:10
  • This is what I hate about the stdio API, whenever you need to do something nontrivial like resize a file, or move a file without copying it over and deleting the old one, you are out of luck in terms of portability. – Thomas Dec 19 '12 at 05:48

3 Answers3

20

fopen actually tries to open the file, which you can't do if you don't have read access. In order to check whether the file exists without opening it, use stat; stat gives you metadata about the file, and requires only read access to the directory containing the file, not the file itself.

int doesFileExist(const char *filename) {
    struct stat st;
    int result = stat(filename, &st);
    return result == 0;
}

You could get fancier by checking errno if result is not 0; if errno is ENOENT then the file does not exist, if it is ENOTDIR then part of the path you provided is not a directory, if it's EACCESS then you didn't have read permission on one of the directories in the path and so stat can't give you an answer, and so on.

Also, be aware that if you're on a platform with symlinks (any Unix-like, or Windows Vista or later), that you should be aware of whether you are querying about the symlink or the file it points to. If you call stat, then you are asking about the file it points to; if you have a symlink dir/link which points to other/file, then stat will return results about other/file (which is usually what you want, since that's what you would get if you opened the file). However, if you are curious about the link itself (if you want to know "does dir/link exist, even if other/file does not?"), then you should use lstat().

stat() works on Windows as a compatibility wrapper (they prefer you use _stat(), and will warn if you don't), but it's generally better to use the native platform APIs. On Windows, you should probably use GetFileAttributes():

int doesFileExist(const char *filename) {
    return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
}
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
1

You are not really checking whether the file exists here... You are checking if you can open it with read access. It could fail for reasons other than the file not existing. As you have seen, you might not have read permission. It could also be that the file is locked.

Check this answer:

What's the best way to check if a file exists in C? (cross platform)

It suggests using stat, which should work in most cases except if you don't have read access on the directory in which the file resides.

Community
  • 1
  • 1
paddy
  • 60,864
  • 6
  • 61
  • 103
-1

On Linux (and many other systems), you can use opendir() and friends to list directories. I guess read-only files will show up. There should be similar functions available on other platforms.

Roman Dmitrienko
  • 3,375
  • 3
  • 37
  • 48