本问题已经有最佳答案,请猛点这里访问。
如何确定在Linux中使用C++的目录(不是文件)存在吗?我尝试使用stat()函数,但当找到文件时,它返回正值。我只想找出输入的字符串是否是一个目录,而不是别的什么。
stat()应该工作。你怎么用的?
结构stat st;cout
根据man(2)stat,您可以在st_模式字段上使用s_isdir宏:
bool isdir = S_ISDIR(st.st_mode);
另一方面,我建议使用boost和/或qt4,如果您的软件可以在其他OSS上运行,那么跨平台支持就更容易了。
这是正确的答案。
在including、andi get the compiler error,g++reports"error:'s诳iddir'was not declared in this scope"之后。有人知道会发生什么吗?
巴哈。Typo。S iddir->S isdir。
我在这里找到的东西怎么样
#include
bool DirectoryExists( const char* pzPath )
{
if ( pzPath == NULL) return false;
DIR *pDir;
bool bExists = false;
pDir = opendir (pzPath);
if (pDir != NULL)
{
bExists = true;
(void) closedir (pDir);
}
return bExists;
}
或使用STAT
struct stat st;
if(stat("/tmp",&st) == 0)
if(st.st_mode & S_IFDIR != 0)
printf(" /tmp is present
");
也许没有那么糟糕,但是上面给出的示例并没有那么有效,下面的示例是我已经在使用的,除了我正在使用的!= = =
是的,最下面的一个需要更新黑尘的额外and条件。(myStat.st_mode) & S_IFMT) == S_IFDIR)。谢谢黑尘。
上面给出的例子是唯一对我有用的例子,所以我现在就接受它作为答案。
不必在目录上尝试opendir;请使用s_isdir宏。
您是说如果dir存在,它应该是if(st.st_mode&s_ifdir==0)????
如果可以查看boost文件系统库。这是一种以通用和可移植的方式处理此类问题的好方法。
在这种情况下,可以使用:
#include"boost/filesystem.hpp"
using namespace boost::filesystem;
...
if ( !exists("test/mydir" ) ) {bla bla}
致命错误:boost/filesystem.hpp:未终止此类文件或目录编译。
好吧,你需要下载并安装Boost…但我怀疑你会后悔的:)
安装后仍不工作,"在using声明中不允许"namespace"boost::filesystem":。/
抱歉,更正了答案…
为什么要推进通往黑暗的道路?
我理解你的问题的方式是:你有一条路径,比如说,/foo/bar/baz(baz是一个文件),你想知道/foo/bar是否存在。如果是这样,解决方案看起来像这样(未经测试):
char *myDir = dirname(myPath);
struct stat myStat;
if ((stat(myDir, &myStat) == 0) && (((myStat.st_mode) & S_IFMT) == S_IFDIR)) {
// myDir exists and is a directory.
}
不,我的意思是"/foo/bar/baz"和"/foo/bar/baz"使用相同的字符串,但一个baz是目录,另一个是文件。使用stat()它只告诉我字符串是否存在,而不是它是文件或目录。
怎么会这样呢?不能有两个同名的不同目录项;要么是/foo/bar/baz不存在,要么是存在且是目录,要么是存在且不是目录;不能同时作为目录和非目录存在。
啊,所以你想知道它是什么。在这种情况下,一个人的答案就是你想要的。
这也是一个正确的答案,除了使用st_mode & S_IFMT而不是S_ISDIR是不好的风格。
@metadark:stat会在st_mode标志中告诉您路径是否是目录。使用我的代码检查目录标志或S_ISDIR宏,如one的答案所示。
我喜欢C++,这是直观的,所以很容易记住,它的工作!
如果你想知道一个目录是否存在是因为你想对它做些什么(在里面创建一个文件/目录,扫描它的内容等),你应该继续做你想做的,然后检查它是否失败,如果失败,向用户报告strerror(errno)。这是在Unix下进行编程的一个一般原则:不要试图弄清楚您想要做的事情是否有效。尝试一下,然后看看是否失败。
如果您想在某个目录不存在(例如,如果您想创建一个文件和所有必要的包含目录)而导致失败时采取特殊的行为,那么在open失败后,您需要检查errno == ENOENT。
我看到有人建议使用boost::filesystem。我想支持这个建议,但遗憾的是我不能,因为boost::filesystem不只是header,而且Boost的所有非header-only模块都有一个可怕的跟踪记录,如果您在不重新编译应用程序的情况下升级共享库,或者即使您没有用完全相同的方法编译应用程序,都会导致神秘的中断。用于编译共享库的标志。维护的痛苦是不值得的。
如果它以文件的形式检测到它,它仍然会继续,并创建一个看起来已损坏的tar文件。哦,是的,如果我还没说的话,我就试着在目录上涂沥青。
从目录创建归档文件的第一步是扫描目录,所以为什么不直接调用opendir,看看它是否失败(当应用于普通文件时应该调用哪个)?
在C++ 17 **中,EDCOX1(7)提供了两个变量来确定路径的存在:
is_directory()确定路径是否是一个目录并且确实存在于实际的文件系统中。
exists()只是确定路径是否存在于实际的文件系统中(如果是目录,则不检查)。
示例(无错误处理):
#include
#include // C++17
//#include // C++14
namespace fs = std::filesystem;
//namespace fs = std::experimental::filesystem; // C++14
int main()
{
// Prepare.
const auto processWorkingDir = fs::current_path();
const auto existingDir = processWorkingDir /"existing/directory"; // Should exist in file system.
const auto notExistingDir = processWorkingDir /"fake/path";
const auto file = processWorkingDir /"file.ext"; // Should exist in file system.
// Test.
std::cout
<
"
<
"
<
";
std::cout
<
"
<
"
<
}
可能的输出:
existing dir: 1
fake dir: 0
existing file: 0
existing dir: 1
fake dir: 0
existing file: 1
**在C++ 14中使用EDCOX1(10)
两个函数都会在出现错误时抛出filesystem_error。如果要避免捕获异常,请使用带有std::error_code的重载变量作为第二个参数。
#include
#include
namespace fs = std::filesystem;
bool isExistingDir(const fs::path& p) noexcept
{
try
{
return fs::is_directory(p);
}
catch (std::exception& e)
{
// Output the error message.
const auto theError = std::string{ e.what() };
std::cerr << theError;
return false;
}
}
bool isExistingDirEC(const fs::path& p) noexcept
{
std::error_code ec;
const auto isDir = fs::is_directory(p, ec);
if (ec)
{
// Output the error message.
const auto theError = ec.message();
std::cerr << theError;
return false;
}
else
{
return isDir;
}
}
int main()
{
const auto notExistingPath = fs::path{"\xa0\xa1" };
isExistingDir(notExistingPath);
isExistingDirEC(notExistingPath);
}
为什么先用is_directory(),然后用exists()秒?另外,是否真的需要exists()?
在Windows上,我做了:if (!is_directory("myDir")) { create_directory("myDir"); if (!is_directory("myDir")) { return false; } },它工作得很好(如果文件夹不存在,就创建了它,如果它作为文件夹存在,就不创建;如果它作为文件存在,就返回false)。
@安德鲁谢谢你的暗示,埃多克斯1〔9〕的确是多余的!我已经更新了示例。因为这个问题不包括创建目录,所以我在答案中省略了这个问题。