在Windows C应用程序中,我想验证传递给函数的参数,以确保指定的路径存在。*
如何在C中检查Windows上是否存在目录?
*我了解你可以进入竞争条件,在你检查存在的时间和使用它不再存在的路径的时间之间,但我可以处理。
当权限发挥作用时,明确知道目录是否存在可能会变得棘手。在尝试确定目录是否存在时,该进程可能无权访问目录或父目录。 这可以满足我的需求。如果目录不存在或者我无法访问它,则在我的应用程序中都将两者视为无效路径故障,因此我不需要区分。如果您的解决方案提供了这种区别,则(虚拟)奖励积分。
C语言,C运行时库或Win32 API中的任何解决方案都很好,但理想情况下我想坚持常用的库(例如kernel32,user32等)并避免涉及加载非的解决方案标准库(如Shlwapi.dll中的PathFileExists)。如果您的解决方案是跨平台的,那么(虚拟)奖励积分。
How can we check if a file Exists or not using Win32 program?
答案 0 :(得分:84)
做这样的事情:
BOOL DirectoryExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
GetFileAttributes()方法包含在Kernel32.dll中。
答案 1 :(得分:22)
这是一个完全与平台无关的解决方案(使用标准C库)
编辑:要在Linux中进行编译,请将<io.h>
替换为<unistd.h>
,将_access
替换为access
。对于真正的平台无关解决方案,请使用Boost FileSystem库。
#include <io.h> // For access().
#include <sys/types.h> // For stat().
#include <sys/stat.h> // For stat().
bool DirectoryExists( const char* absolutePath ){
if( _access( absolutePath, 0 ) == 0 ){
struct stat status;
stat( absolutePath, &status );
return (status.st_mode & S_IFDIR) != 0;
}
return false;
}
支持MBCS和UNICODE构建的Windows特定实现:
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <tchar.h>
BOOL directory_exists( LPCTSTR absolutePath )
{
if( _taccess_s( absolutePath, 0 ) == 0 )
{
struct _stat status;
_tstat( absolutePath, &status );
return (status.st_mode & S_IFDIR) != 0;
}
return FALSE;
}
答案 2 :(得分:9)
如果您可以使用Shell轻量级API(shlwapi.dll)链接,则可以使用PathIsDirectory function。
答案 3 :(得分:4)
答案 4 :(得分:0)
所以,这个问题充满了边缘情况。真正的答案是这样的:
BOOL DirectoryExists(LPCTSTR szPath, BOOL *exists)
{
*exists = FALSE;
size_t szLen = _tcslen(szPath);
if (szLen > 0 && szPath[szLen - 1] == '\\') --szLen;
HANDLE heap = GetProcessHeap();
LPCTSTR szPath2 = HeapAlloc(heap, 0, (szlen + 3) * sizeof(TCHAR));
if (!szPath2) return FALSE;
CopyMemory(szPath2, szPath, szLen * sizeof(TCHAR));
szPath2[szLen] = '\\';
szPath2[szLen + 1] = '.';
szPath2[szLen + 2] = 0;
DWORD dwAttrib = GetFileAttributes(szPath2);
HeapFree(heap, 0, szPath2);
if (dwAttrib != INVALID_FILE_ATTRIBUTES) {
*exists = TRUE; /* no point checking FILE_ATTRIBUTE_DIRECTORY on "." */
return TRUE;
}
/*
* If we get anything other than ERROR_PATH_NOT_FOUND then something's wrong.
* Could be hardware IO, lack of permissions, a symbolic link pointing to somewhere
* you don't have access, etc.
*/
return GetLastError() != ERROR_PATH_NOT_FOUND;
}
DirectoryExists 的正确结果是三态。共有三种情况,您需要处理所有情况。要么存在,要么不存在,或者您无法检查。我在生产中丢失了数据,因为 SAN 向检查函数返回 NO,然后让我在下一行代码中创建一些破坏它的东西。不要犯微软在 C# 中设计 File.Exists()
API 时犯过的错误。
但是,我看到很多检查都是非常有用的。不要像if (
目录不存在) CreateDirectory()
那样写;只需写CreateDirectory() if (GetLastError() != 0 && GetLastError() != ERROR_ALREADY_EXISTS
。或者与 RemoveDirectory()
相反;只需将其删除并检查是否没有错误或未找到路径。