如何使用 C++17 的文件系统检查路径是否引用 Windows 中的卷?
How to check if a path refers to a volume in Windows with C++17's filesystem?
我在 Windows 上使用 C++17。据我所知,std::filesystem
没有 is_root()
函数或类似的东西告诉我路径是否直接指向 C: 或 D: 或任何其他卷。我错过了什么吗?
目前我正在这样做:
if (path.parent_path() == path)
{
//
}
看起来它可以正常工作,但我不知道这是否遗漏了任何边缘情况。有没有更好的方法?
编辑:
我想检查整个路径是否只是卷名(可能后跟一个可选的斜杠或反斜杠)。
所以,如果有这样的函数,我希望它的行为如下:
namespace fs = std::filesystem;
is_root(fs::path{ "C:" }); // true
is_root(fs::path{ "D:\"}); // true
is_root(fs::path{ "C:/users" }) // false
is_root(fs::current_path()) // usually false, unless the executable was started directly in C: or D: or any other drive
首先,检查是否has_root_name()
;没有一个,显然没有指定卷
困难的部分是弄清楚它是否只有有根名称。这很复杂,因为如果路径指定了根目录,您还想忽略它。
迭代器范围是一个很好的、性能友好的解决方案。如果它有一个根名,那么 begin()
指向那个根名。因此,如果您增加它,它会指向路径中的下一个组件。
如果路径同时包含根名和根目录,则根名后的部分为根目录。因此,如果您递增超过 that,迭代器要么指向另一个组件,要么已经到达范围的 end
。如果它在 end
,那么什么都没有,你知道路径是 "just a volume"。
代码如下所示:
bool is_volume(const fs::path &p)
{
if(!p.has_root_name()) return false;
auto it = p.begin();
++it; //Skip the root-name
if(p.has_root_directory())
++it; //Skip the root-directory.
if(it == p.end())
return true;
return false;
}
我在 Windows 上使用 C++17。据我所知,std::filesystem
没有 is_root()
函数或类似的东西告诉我路径是否直接指向 C: 或 D: 或任何其他卷。我错过了什么吗?
目前我正在这样做:
if (path.parent_path() == path)
{
//
}
看起来它可以正常工作,但我不知道这是否遗漏了任何边缘情况。有没有更好的方法?
编辑:
我想检查整个路径是否只是卷名(可能后跟一个可选的斜杠或反斜杠)。
所以,如果有这样的函数,我希望它的行为如下:
namespace fs = std::filesystem;
is_root(fs::path{ "C:" }); // true
is_root(fs::path{ "D:\"}); // true
is_root(fs::path{ "C:/users" }) // false
is_root(fs::current_path()) // usually false, unless the executable was started directly in C: or D: or any other drive
首先,检查是否has_root_name()
;没有一个,显然没有指定卷
困难的部分是弄清楚它是否只有有根名称。这很复杂,因为如果路径指定了根目录,您还想忽略它。
迭代器范围是一个很好的、性能友好的解决方案。如果它有一个根名,那么 begin()
指向那个根名。因此,如果您增加它,它会指向路径中的下一个组件。
如果路径同时包含根名和根目录,则根名后的部分为根目录。因此,如果您递增超过 that,迭代器要么指向另一个组件,要么已经到达范围的 end
。如果它在 end
,那么什么都没有,你知道路径是 "just a volume"。
代码如下所示:
bool is_volume(const fs::path &p)
{
if(!p.has_root_name()) return false;
auto it = p.begin();
++it; //Skip the root-name
if(p.has_root_directory())
++it; //Skip the root-directory.
if(it == p.end())
return true;
return false;
}