10

I'm attempting to open a file in a C application. How do I check that a file exists before trying to read from it?

Dunc
  • 7,688
  • 10
  • 31
  • 38
  • same as http://stackoverflow.com/questions/650739/checking-whether-a-file-can-be-opened-using-portable-c – Coren Feb 28 '12 at 14:12

6 Answers6

18

Try to open it:

FILE * file;
file = fopen("file_name", "r");
if (file){
   //file exists and can be opened 
   //...
   // close file when you're done
   fclose(file);
}else{
   //file doesn't exists or cannot be opened (es. you don't have access permission)
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Heisenbug
  • 38,762
  • 28
  • 132
  • 190
  • 1
    "file doesn't exists" - doesn't quite follow, it might exist but you don't have permission to open it for reading. But the questioner probably really needs to know whether he can read it, and that's what this tells you. – Steve Jessop Feb 28 '12 at 14:30
  • 1
    Also remember to `fclose(file)` when you're done with it, if it did exist. It is easy to forget about closing the stream when all you're doing is just seeing whether the file opens at all, but if you don't, then neither your application nor other applications will be able to open the file until your application exits, etc., which is to protect against multiple programs doing write operations on the same file simultaneously, as that wouldn't make any sense to do. – rsethc Oct 25 '16 at 22:56
  • 1
    the code exists a redundant bracket on line 2. – colin-zhou Jan 03 '20 at 01:30
7

Existence: call stat(), check the return code, which has no side effects. On UNIX, call access() as well.

You would do this in the event you're simply doing what you asked, does FileA exist, not necessarily can I open it. Example: In UNIX a file with execute-only permissions would fail open, but still exist.

With stat you can check st_mode for access. However since you intend to open the file anyway, fopen or open are probably what you want.

jim mcnamara
  • 16,005
  • 2
  • 34
  • 51
  • 1
    stat? access? open? Who asked for non-standard Unix functions? This answer is off-topic. – Lundin Feb 28 '12 at 14:27
  • 4
    @Lundin: He didn't ask for standard non-Unix functions either. This answer is on topic. Besides they're all standard on POSIX, which itself *is* a standard. – netcoder Feb 28 '12 at 15:02
  • 1
    @netcoder He did. It is tagged C, so therefore we must assume the OP is asking for C language functions. The C language is defined in the ISO standard, there is no other definition for it. Posix is a standard for operative systems, file handling doesn't automatically mean that an OS is involved. – Lundin Feb 28 '12 at 15:54
  • 3
    @Lundin: Don't be so pedantic. You assume too much. According to your definition, then a huge amount of questions tagged as C shouldn't be tagged as such because they ask about or are answered with "non-C language functions". It's ridiculous. This answer is useful in its own right. You don't seem to quite understand the downvote privilege. – netcoder Feb 28 '12 at 16:30
  • @Lundin: Take your trolling elsewhere. `stat` is not obscure at all. Unix is not the preferred OS on SO. But unless the OP asks for a specific OS, I don't see why answers relating to the most-used OSes (that is, *NIX and Windows) wouldn't be good answers. – netcoder Feb 28 '12 at 21:05
3

You could do something like this:

bool file_exists(const char * filename) {
    if (FILE * file = fopen(filename, "r")) {
        fclose(file);
        return true;
    }
    return false;
}

Basically just open the file and check if it succeeded.

Tim
  • 2,051
  • 17
  • 36
  • The problem with a function like this is that the answer can become false in the gap between closing the file and returning, because the filesystem is a system-wide global mutable resource. So when you "check a file exists before trying to read from it", where possible you should always use the same filehandle to read as you used for the check. There are cases where it doesn't matter that your information is out of date, in which case you could also use `stat` where available. – Steve Jessop Feb 28 '12 at 14:29
2

You should check the result of fopen.

FILE *fp;

if (!(fp = fopen(name, "r"))) {
    perror("fopen");
    /* Handle error, return, exit, try again etc. */
}

/* Normal code goes on. */

If fopen returns NULL, the file is for some reason inaccessible. It could be missing or perhaps the process doesn't have permissions.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 4
    ... and check the value of `errno` for the reason why `fopen` failed; `ENOENT` if the file doesn't exist. – Fred Foo Feb 28 '12 at 13:33
1

Testing if file exists isn't too hard. There are numerous of ways to do it, but after reading up on this I decided the best method is using the stat method. I suggest using stat, because I think it is important to be able to distinguish files and directories. I suggest this for both Windows and Unix.

Here is provided two links to the documentation on MSDN and opengroup.

Windows

Unix

k9dog
  • 31
  • 4
0

You open the file and check the return value of fopen() or open().

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271