Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查目录是否存在的便携式方法[Windows/Linux,C]_C_File_Directory_File Exists - Fatal编程技术网

检查目录是否存在的便携式方法[Windows/Linux,C]

检查目录是否存在的便携式方法[Windows/Linux,C],c,file,directory,file-exists,C,File,Directory,File Exists,我想检查给定的目录是否存在。我知道如何在Windows上执行此操作: BOOL DirectoryExists(LPCTSTR szPath) { DWORD dwAttrib = GetFileAttributes(szPath); return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); } 和Linux: DIR* di

我想检查给定的目录是否存在。我知道如何在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;
}
#包括
#包括
#包括
#包括
int dirExists(常量字符*路径)
{
结构统计信息;
如果(状态(路径和信息)!=0)
返回0;
else if(info.st_mode&S_IFDIR)
返回1;
其他的
返回0;
}
int main(int argc,字符**argv)
{
const char*path=“./TEST/”;
printf(“%d\n”,dirExists(path));
返回0;
}
使用,这将为您提供一种可移植的方式来做这些事情,并为您抽象掉所有丑陋的细节。

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

glib提供了一个功能,可以实现这一点。

也适用于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 );
#包括
#包括
结构统计信息;
如果(状态(路径名和信息)!=0)
printf(“无法访问%s\n”,路径名);
else if(info.st_mode&S_IFDIR)//S_ISDIR()在我的windows上不存在
printf(“%s是一个目录\n”,路径名);
其他的
printf(“%s”不是目录\n“,路径名);

因为我发现上面批准的答案不够清晰,op提供了一个他/她将使用的不正确的解决方案。因此,我希望下面的例子能帮助其他人。该解决方案或多或少也是可移植的

/******************************************************************************
 * 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;
}
/******************************************************************************
*检查目录是否存在。注意:此方法仅检查
*完整路径的存在性以及路径叶是否为dir。
*
*@return>0如果dir存在并且是dir,
*0如果目录不存在或存在但不是目录,


*使用C++17,您可以使用
std::filesystem::is_directory
函数()。它接受一个
std::filesystem::path
对象,该对象可以用unicode路径构造。

哦,我怀疑在C中是否有一种可移植的方法来实现这一点。你只需要使用
#define
来检查你的代码是为什么操作系统编译的,并为每个你想编译的操作系统添加代码。当标准库有办法处理如何简单地创建一个文件(带有随机文件名)时,并不是每个人都愿意为一个简单的函数增加和扩充代码库请注意,从这样的测试中得到的任何答案都会立即过时。您刚才检查的目录在使用时可以被删除或移动-这种类型的代码本身就有缺陷。这种类型的“先检查后使用”错误甚至有:“在软件开发中,检查时间到使用时间(TOCTOU、TOCTOU或TOC/TOU)是一类由竞争条件引起的软件错误,该竞争条件涉及检查系统某一部分的状态(如安全凭证)和使用该检查的结果。”如果需要在特定目录中创建文件,只需在该目录中创建文件即可。如果目录不存在,您将得到一个错误。首先检查目录是否存在并不能保证您可以创建该文件,因此您必须处理创建错误。在Xubuntu 12.04和Windows XP上检查此项,成功了,谢谢@阿尔克:你确定吗?我在我的第一篇文章中添加了一个示例代码,它在没有任何预处理器指令的情况下工作,没有警告(我在Xubuntu上使用gcc,在Windows上使用MinGW)@alk我在发布之前尝试过,没有预处理器指令needed@IngoLeonhardt:您使用了哪种编译器/环境?我无法在OSX 10.11上运行此功能。XCode7说:“调用stat没有匹配的函数”。不过,修复方法是在stat()调用中执行pathname.c_str(),因为我的路径名是std::string。至少在Linux上,您还需要为
ENOTDIR
提供特殊处理。@JohnBollinger,谢谢您的建议。我对回复进行了编辑,将其包括在内,因为它似乎是有意义的。然而,在我的测试中,我没有触发这个案例。我不太理解stat的手册页和这个错误。有人是如何在测试中触发此操作的?
ENOTDIR
表示给定路径中的一个名称(除最后一个名称外)存在,但不是目录。因此,如果
/tmp/regular\u file
确实是一个常规文件,那么尝试统计
/tmp/regular\u file/foo
应该会导致此错误。这与statting
/tmp/non_existent/foo
/tmp/foo/non_existant
不同;后两个应该都是错误的
enoint
。我不会投反对票。但是如果你想提供一个更清晰的例子,最好也包含必要的include。在整个堆栈溢出页面上(您的答案和其他答案)没有提到“include”。但是从我所做的其他阅读中,我知道这是一个缺少的导入。在MSVC编译中,我没有得到错误,在GCC编译中,我得到了错误。谢谢你,因为这是标准库的一部分,不需要臃肿的第三方库。这应该是公认的答案