Reputation: 1130
I have a full path stored in char full_path[1000]
and I'd like to know whether anything exists at that location.
(The next thing my code would do after this check is create something at that location, but I want it to count as an error if there is already something there instead of clearing the spot with the equivalent of rm -rf
)
The spot might be occupied by a file or a directory or even a link to some no-longer-existing-target e.g.:
lrwxrwxrwx 1 user grp 4 Jun 16 20:02 a-link -> non-existent-thing
With an invalid link, access(full_path, F_OK)
is going to tell me I can't access full_path
and that could be because (1) nothing exists there or because (2) the link is invalid.
Given that, what's the best way to determine if anything exists at full_path
?
Upvotes: 0
Views: 96
Reputation: 1130
Since the next thing we plan to do is create something at that location, and since we want to treat it as an error if something already exists there, then let's not bother checking. Just attempt the create and exit with an error if it fails. The create step uses symlink
so if it fails we can use strerror(errno)
for the explanation of any failure.
To create a file in general (vs just a symlink), EOF points out in comments that open(path, O_CREAT|O_EXCL, mode)
will return failure (-1) if the file already exists, and create the file otherwise. This is atomic and safe (unlike trying to stat
) and guaranteed to work atomically on POSIX (with the possible exception of NFS).
Upvotes: 0
Reputation: 1791
You simply cannot do that in a cross-platform obvious way. stat()
and fopen()
would not work. You can, though, use the OS API, for example, on windows you could use WinAPI
with the example code:
int doesFileExist(TCHAR* path)
{
WIN32_FIND_DATA FindFileData;
HANDLE handle = FindFirstFile(path, &FindFileData) ;
int found = (handle != INVALID_HANDLE_VALUE);
if(found)
{
FindClose(handle);
}
return found;
}
If you just want to check if anything exists, finding any file (again, using Windows API) would also work, you could just go directory by directory to check if it exists, if one doesn't - return an error. Keep going until you got to the directory then check for the certain file in the way mentioned above.
Say you have C:/Dir1/Dir2/Dir3/file.txt
then you'd go to C:
first, then check if Dir1
exists, if it does - go to it, if it doesn't return an error. Same for Dir2
and so on up until you get to the last directory and check for the file OR if you don't check for a certain file and for any item - just try using the functions mentioned in MSDN
for finding first file or first directory.
Upvotes: 1