我有一个存储在char full_path[1000]
的完整路径,我想知道该位置是否存在任何东西。
(在此检查之后,我的代码要做的下一件事是在该位置创建一些东西,但如果那里已经有东西,我希望它算作错误,而不是用相当于rm -rf
清除该点)
该位置可能被文件或目录占用,甚至是指向某个不再存在的目标的链接,例如:
lrwxrwxrwx 1 user grp 4 Jun 16 20:02 a-link -> non-existent-thing
对于无效链接,access(full_path, F_OK)
会告诉我我无法访问full_path
,这可能是因为 (1) 那里不存在任何东西或因为 (2) 链接无效。
鉴于此,确定full_path
是否存在任何东西的最佳方法是什么?
你根本无法以跨平台的明显方式做到这一点。 stat()
和fopen()
是行不通的。但是,您可以使用操作系统API,例如,在Windows上,您可以将WinAPI
与示例代码一起使用:
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;
}
如果您只想检查是否存在任何内容,查找任何文件(再次使用 Windows API)也可以,您可以逐个目录检查它是否存在,如果没有 - 返回错误。继续前进,直到到达目录,然后以上述方式检查某个文件。
假设你有C:/Dir1/Dir2/Dir3/file.txt
那么你会先去C:
,然后检查Dir1
是否存在,如果存在 - 去它,如果它没有返回错误。对于Dir2
也是如此,依此类推,直到您到达最后一个目录并检查文件,或者如果您不检查某个文件和任何项目 - 只需尝试使用 MSDN
中提到的函数查找第一个文件或第一个目录。
由于我们计划做的下一件事是在该位置创建一些东西,并且由于我们希望将其视为错误(如果那里已经存在某些东西),那么我们不要费心检查。只需尝试创建并在失败时退出并显示错误。创建步骤使用symlink
因此,如果失败,我们可以使用 strerror(errno)
来解释任何失败。
为了创建一般的文件(而不是只是一个符号链接),EOF在注释中指出,如果文件已经存在,open(path, O_CREAT|O_EXCL, mode)
将返回失败(-1),否则将创建文件。这是原子和安全的(不像试图stat
),并保证在POSIX上原子工作(NFS可能除外)。