C++;-确定Linux中是否存在目录(不是文件) 如何判断Linux中使用C++的目录(不是文件)的存在?我尝试使用stat()函数,但在找到文件时返回正值。我只想找到输入的字符串是否是目录,而不是其他内容。
我找到的内容怎么样 根据需要,您可以在st_模式字段上使用S_ISDIR宏:C++;-确定Linux中是否存在目录(不是文件) 如何判断Linux中使用C++的目录(不是文件)的存在?我尝试使用stat()函数,但在找到文件时返回正值。我只想找到输入的字符串是否是目录,而不是其他内容。,c++,linux,directory,exists,C++,Linux,Directory,Exists,我找到的内容怎么样 根据需要,您可以在st_模式字段上使用S_ISDIR宏: bool isdir = S_ISDIR(st.st_mode); 附带说明,如果你的软件可以在其他操作系统上运行,我建议使用Boost和/或Qt4来简化跨平台支持。我理解你的问题的方式是:你有一条路径,比如说,/foo/bar/baz(baz是一个文件),你想知道/foo/bar是否存在。如果是这样,解决方案看起来是这样的(未经测试): 如果你能查一下。这是一种以通用和可移植的方式处理此类问题的好方法 在这种情况下
bool isdir = S_ISDIR(st.st_mode);
附带说明,如果你的软件可以在其他操作系统上运行,我建议使用Boost和/或Qt4来简化跨平台支持。我理解你的问题的方式是:你有一条路径,比如说,
/foo/bar/baz
(baz是一个文件),你想知道/foo/bar
是否存在。如果是这样,解决方案看起来是这样的(未经测试):
如果你能查一下。这是一种以通用和可移植的方式处理此类问题的好方法
在这种情况下,只需使用:
#include "boost/filesystem.hpp"
using namespace boost::filesystem;
...
if ( !exists( "test/mydir" ) ) {bla bla}
如果你想知道某个目录是否存在是因为你想对它做些什么,如果它存在(在里面创建一个文件/目录,扫描它的内容,等等),你应该继续做你想做的事情,然后检查它是否失败,如果是,向用户报告
strerror(errno)
。这是Unix下编程的一般原则:不要试图弄清楚您想做的事情是否可行。尝试一下,然后看看是否失败
如果您想在由于目录不存在而失败的情况下(例如,如果您想创建一个文件和所有必要的包含目录)表现出特别的行为,您可以在打开失败后检查errno==enoint
我看到一个响应者建议使用boost::filesystem
。我想支持这一建议,但遗憾的是我不能,因为boost::filesystem
不是仅头文件,而且boost的所有非头文件模块都有一个可怕的记录,如果您升级共享库而不重新编译应用程序,会导致神秘的破坏,或者,即使您只是没有使用编译共享库时使用的完全相同的标志编译应用程序。维护是不值得的。在C++17**中,提供了两种变体来确定路径的存在:
确定路径是否为目录且是否存在于实际文件系统中
仅确定路径是否存在于实际文件系统中(如果是目录,则不检查)
示例(无错误处理):
**在C++14中提供
这两个函数都会在出现错误时抛出。如果要避免捕获异常,请使用重载变量作为第二个参数
#include <filesystem>
#include <iostream>
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);
}
#包括
#包括
名称空间fs=std::filesystem;
bool isExistingDir(常量fs::path&p)不例外
{
尝试
{
返回fs::is_目录(p);
}
捕获(标准::异常&e)
{
//输出错误消息。
const auto theError=std::string{e.what()};
标准::cerrstat()应该工作。你如何使用它?StuttStAt;Cuth-imHo,重复标志是不正确的,因为另一个问题是关于搜索系统调用,而这个问题是关于C++的一般方法。它可能不是那么糟糕,但是上面给出的例子实际上不是很有效,而最下面的例子就是我已经使用的,EX。除了我使用的!=而不是==ya之外,底部的一个需要用DarkDust的额外和条件更新。(myStat.st_模式)&S_-IFMT)==S_-IFDIR
。谢谢DarkDust。上面给出的示例是唯一对我有效的示例,因此我现在接受它作为答案。没有必要在目录上尝试opendir;使用S_-ISDIR宏。你是说如果目录存在,它应该是if(st.st_模式&S_-IFDIR==0)??不,我的意思是“/foo/bar/baz”和“/foo/bar/baz”使用相同的将被视为相同的字符串,但一个baz是目录,另一个是文件它只告诉我字符串是否存在,而不是它是否是一个文件或目录。这怎么可能发生?你不能有两个同名的不同目录项;/foo/bar/baz
不存在,或者它存在并且是一个目录,或者它存在并且不是一个目录;它不能同时作为一个目录而不是一个目录存在。啊,那么你呢你想知道它是哪一个。在这种情况下,其中一个答案就是你想要的。这也是一个正确的答案,除了使用st_模式&s_IFMT
而不是s_ISDIR
是糟糕的风格。@MetaDark:stat会告诉你路径是否是st_模式下的目录标志或S_ISDIR
宏,如OneOfOne的答案所示。致命错误:boost/filesystem.hpp:没有终止此类文件或目录编译。嗯,您需要下载并安装boost…但我怀疑您会后悔:)安装后仍不工作,“命名空间'boost::filesystem'不允许使用声明":/抱歉,更正了答案…为什么boost the path to Dark?如果它检测到它是一个文件,它仍然会继续,并创建一个似乎已损坏的tar文件。哦,是的,如果我还没有说过,我正在尝试对目录进行tar。从目录创建存档的第一步是扫描目录,那么为什么不能调用opendir
并查看它是否失败(应用于普通文件时应该失败)?包括,并且我得到编译器错误后,g++报告“错误:'S_IDDIR'未在此范围内声明”。有人知道可能发生了什么吗?Bahah.Typo.S_IDDIR->S_ISDIR。为什么先使用is_directory()
然后再使用exists()
second?还有,exists()
真的需要吗?在Windows上,我做了:if(!is_目录(“myDir”){create_目录(“myDir”);if(!is_目录(“myDir”){return false;}}
并且它工作得很好(如果创建了文件夹)
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.
}
#include "boost/filesystem.hpp"
using namespace boost::filesystem;
...
if ( !exists( "test/mydir" ) ) {bla bla}
#include <iostream>
#include <filesystem> // C++17
//#include <experimental/filesystem> // 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
<< "existing dir:\t" << fs::is_directory(existingDir) << "\n"
<< "fake dir:\t" << fs::is_directory(notExistingDir) << "\n"
<< "existing file:\t" << fs::is_directory(file) << "\n\n";
std::cout
<< "existing dir:\t" << fs::exists(existingDir) << "\n"
<< "fake dir:\t" << fs::exists(notExistingDir) << "\n"
<< "existing file:\t" << fs::exists(file);
}
existing dir: 1
fake dir: 0
existing file: 0
existing dir: 1
fake dir: 0
existing file: 1
#include <filesystem>
#include <iostream>
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);
}