83

我想检查给定目录是否存在。我知道如何在 Windows 上执行此操作:

BOOL DirectoryExists(LPCTSTR szPath)
{
  DWORD dwAttrib = GetFileAttributes(szPath);

  return (dwAttrib != INVALID_FILE_ATTRIBUTES && 
         (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

和 Linux:

DIR* dir = opendir("mydir");
if (dir)
{
    /* Directory exists. */
    closedir(dir);
}
else if (ENOENT == errno)
{
    /* Directory does not exist. */
}
else
{
    /* opendir() failed for some other reason. */
}

但是我需要一种可移植的方式来做到这一点。无论我使用什么操作系统,有什么方法可以检查目录是否存在?也许C标准库方式?

我知道我可以使用预处理器指令并在不同的操作系统上调用这些函数,但这不是我要求的解决方案。

我结束了这个,至少现在:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>

int dirExists(const char *path)
{
    struct stat info;

    if(stat( path, &info ) != 0)
        return 0;
    else if(info.st_mode & S_IFDIR)
        return 1;
    else
        return 0;
}

int main(int argc, char **argv)
{
    const char *path = "./TEST/";
    printf("%d\n", dirExists(path));
    return 0;
}
4

6 回答 6

122

stat()也适用于 Linux.、UNIX 和 Windows:

#include <sys/types.h>
#include <sys/stat.h>

struct stat info;

if( stat( pathname, &info ) != 0 )
    printf( "cannot access %s\n", pathname );
else if( info.st_mode & S_IFDIR )  // S_ISDIR() doesn't exist on my windows 
    printf( "%s is a directory\n", pathname );
else
    printf( "%s is no directory\n", pathname );
于 2013-08-07T10:30:17.727 回答
13

使用 C++17,您可以使用std::filesystem::is_directory函数 ( https://en.cppreference.com/w/cpp/filesystem/is_directory )。它接受一个std::filesystem::path可以用 unicode 路径构造的对象。

于 2020-08-27T18:31:02.447 回答
9

由于我发现上述批准的答案缺乏明确性,并且操作人员提供了他/她将使用的错误解决方案。因此,我希望以下示例对其他人有所帮助。该解决方案或多或少也是可移植的。

/******************************************************************************
 * Checks to see if a directory exists. Note: This method only checks the
 * existence of the full path AND if path leaf is a dir.
 *
 * @return  >0 if dir exists AND is a dir,
 *           0 if dir does not exist OR exists but not a dir,
 *          <0 if an error occurred (errno is also set)
 *****************************************************************************/
int dirExists(const char* const path)
{
    struct stat info;

    int statRC = stat( path, &info );
    if( statRC != 0 )
    {
        if (errno == ENOENT)  { return 0; } // something along the path does not exist
        if (errno == ENOTDIR) { return 0; } // something in path prefix is not a dir
        return -1;
    }

    return ( info.st_mode & S_IFDIR ) ? 1 : 0;
}
于 2018-08-27T17:05:08.447 回答
6

使用boost::filesystem,这将为您提供一种可移植的方式来做这些事情,并为您抽象出所有丑陋的细节。

于 2013-08-07T09:51:43.880 回答
2

您可以使用GTK glib从操作系统的东西中抽象出来。

glib 提供了一个g_dir_open()函数,它应该可以解决问题。

于 2013-08-07T10:10:15.090 回答
0

上述示例未使用可用于 Windows 和 Linux 的 [_access]1。使用 [stat]2、_access() 和最新文件系统的 [exists]3 进行测试的代码示例 (Windows)。

#include <iostream>
#include <Windows.h>
#include <io.h>
#include <filesystem>
#include <vector>
#include <string>

using namespace std;
namespace fs = std::filesystem;
std::vector<std::string> DirPaths
{
  "G:\\My-Shcool-2021-22",
  "\\\\192.168.111.8\\Oaco\\RotData\\VV-VA",
  "\\\\192.168.111.15\\5500\\C-drive\\Oaco\\RotateEarthProject",   "\\\\192.168.111.18\\d$\\Mercurial\\Workspace\\HideMoon\\Win32\\Debug", 
"Z:\\SuperSaver" //mapped network drive; symbolic link
};
/* test if the path is a directory
*/
void TestDirExists ()
{
int erno =-1;
struct stat  info {};
auto ErrorMsg = [&](std::string path) 
{
    _get_errno(&erno);
    if (erno == EACCES)
        cout << "access denied  " << path << endl;
    else if (erno == ENOENT)
        cout << "dir path not found  " << path << endl;
    else if (erno == EINVAL)
        cout << "invalid parameter  " << path << endl;        
};

for (const auto &dp : DirPaths)
{
    erno = -1;
    if (stat(dp.c_str(), &info) != 0)
        ErrorMsg(dp);        
    if (_access(dp.c_str(), 0) != 0)
        ErrorMsg(dp);       
    if (fs::exists(dp)==0)
        ErrorMsg(dp);
    if(erno < 0)
         cout << "#Dir Found: " << dp << endl;
}

} [1]:https ://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/access-waccess?view=msvc-170 [2]:https://docs.microsoft。 com/en-us/cpp/c-runtime-library/reference/stat-functions?view=msvc-170 [3]:https ://en.cppreference.com/w/cpp/filesystem/exists

于 2022-01-18T05:53:06.890 回答