Sandeep
Sandeep

Reputation: 19482

Can fopen fail if the file already exists (in write mode)?

I wish to open a new file using fopen("/temp/abc.txt", "w")

I want that if the file already exists, fopen should fail so that I can retry by changing the name. Ex - rename to abc_1.txt.

access() is not my preferred way because there is a possibility that a file gets created after access() call check and before fopen().

What is the better way to handle this?

Upvotes: 1

Views: 1381

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 754780

On a POSIX system, you could use the open() function or one of its relatives to create the file, returning a file descriptor, and then use fdopen() to create a file stream from the file descriptor. Amongst other advantages, this allows you to control the permissions on the file that is created more accurately than the standard I/O library will ever allow.

int fd = open(target_file, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd < 0)
    …report error and return or exit…
FILE *fp = fdopen(fd, "w+");
if (fp == 0)
    …report error and return or exit…

…use file stream fp…

fclose(fp);
// Do not close(fd) too, and especially not before the fclose(fp)!

Upvotes: 3

vgel
vgel

Reputation: 3345

As a random thought, if you don't want to/can't use the "x" flag (which is probably the best way), you could try using "a" instead of "w", and then checking tell() == 0. This will accept both non-existent and empty files, however.

Upvotes: 0

Rufflewind
Rufflewind

Reputation: 8966

In C11, fopen supports a new mode modifier "x" that does what you require. I'm not aware of any portable ways to do this in earlier standards, however.

Most operating systems do support such a flag in their platform-specific file-opening primitives. On POSIX systems this can be achieved with O_EXCL, while on Windows this can be achieved with CREATE_ALWAYS.

Upvotes: 4

Related Questions