0

The function fopen("file-name",a); will return a pointer to the end of the file. If the file exist it is opened, otherwise a new file is created.
Is it possible to use the append mode and open the file only if it already exist? (and return a NULL pointer otherwise).



Thanks in advance

TTK
  • 223
  • 6
  • 21
  • In C you can [check if a file exists](http://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform) before opening it. – Daniel Kleinstein Mar 15 '15 at 23:20
  • 2
    It does not return a pointer to the end of the file - it returns a FILE pointer with the current write location at the end of the current content. You can check if the file already had some content by checking if the "current" location (`ftell(myfile)`) is nonzero, or you can try to check if the file already exists [but that's problematic, because between the check and the actual opening, the file may have been deleted or created] – Mats Petersson Mar 15 '15 at 23:24

2 Answers2

5

To avoid race conditions, opening and checking for existence should be done in one system call. In POSIX this can be done with open as it will not create the file if the flag O_CREAT is not provided.

int fd;
FILE *fp = NULL;
fd = open ("file-name", O_APPEND);
if (fd >= 0) {
  /* successfully opened the file, now get a FILE datastructure */
  fp = fdopen (fd, "a")
}

open may fail for other reasons too. If you do not want to ignore all of them, you will have to check errno.

int fd;
FILE *fp = NULL;
do {
  fd = open ("file-name", O_APPEND);
  /* retry if open was interrupted by a signal */
} while (fd < 0 && errno == EINTR); 
if (fd >= 0) {
  /* successfully opened the file, now get a FILE datastructure */
  fp = fdopen (fd, "a")
} else if (errno != ENOENT) { /* ignore if the file does not exist */
  perror ("open file-name");  /* report any other error */
  exit (EXIT_FAILURE)
}
0

First check if the file already exists. A simple code to do that might be like this:

int exists(const char *fname)
{
    FILE *file;
    if ((file = fopen(fname, "r")))
    {
        fclose(file);
        return 1;
    }
    return 0;
}

It will return 0 if file doesn't exist...

and use it like this:

if(exists("somefile")){file=fopen("somefile","a");}
Jahid
  • 21,542
  • 10
  • 90
  • 108
  • 2
    But it does not tell you if the file would still exist in the moment when you open it for append. – Leonard Michlmayr Mar 15 '15 at 23:46
  • How much time it can take to pass through the if statement and what could have happened in that time? – Jahid Mar 15 '15 at 23:51
  • 2
    Another process or thread could create or delete the file in the meantime. If the scheduler switches to another process after the `if` statement, the time can become longer. – user0815 Mar 15 '15 at 23:53