由于您的错误是指增加recursive_filesystem_iterator
,错误似乎来自for
语句本身,而不是您的后续代码。这for
语句在内部执行增量(operator++
)在recursive_filesystem_iterator
.
对我来说,这感觉像是实施中的一个错误recursive_filesystem_iterator
,和你的代码should无一例外地工作过。但仔细阅读该标准,我认为实现有足够的含糊之处,可以说您看到的行为仍然符合标准。
我没有 c++17 标准的正式副本,因此我在这里提供的参考资料是免费提供的草案n4659.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf.
At 30.10.2.1 Posix conformance
, 它说
Implementations that do not support exact POSIX behavior are encouraged to provide
behavior as close to POSIX behavior as is reasonable given the limitations of actual
operating systems and file systems. If an implementation cannot provide any reasonable
behavior, the implementation shall report an error as specified in 30.10.7. [Note:This
allows users to rely on an exception being thrown or an error code being set when an
implementation cannot provide any reasonable behavior.— end note]
Implementations are not required to provide behavior that is not supported by a
particular file system. [Example: The FAT file system used by some memory cards, camera
memory, and floppy disks does not support hard links, symlinks, and many other features
of more capable file systems, so implementations are not required to support those
features on the FAT file system but instead are required to report an error as described
above.— end example]
所以尝试迭代D:\System Volume Information
如果底层文件系统不允许您这样做,则可能会失败并引发异常。
你的构造函数指定directory_options::skip_permission_denied
。我觉得这应该足以避免异常。
In 30.10.14.1 recursive_directory_iterator members
for operator++
它说:
...then either directory(*this)->path() is recursively iterated into or, if
(options() & directory_options::skip_permission_denied) != directory_options::none
and an error occurs indicating that permission to access directory(*this)->path() is denied,
then directory(*this)->path() is treated as an empty directory and no error is reported.
您得到的实际异常并没有说“权限被拒绝”,所以我想可以说skip_permission_denied
选项不适用于它。这将允许实施operator++
在这种情况下抛出异常。我不喜欢这种解释,因为它似乎是整个想法skip_permission_denied
就是为了避免出现这样的异常。但这不取决于我。 :)
除了尝试将缺陷提交回标准库实现之外,您还能做什么?也许你可以写出一个旧式的for
循环,并使用increment
方法上的recursive_filesystem_iterator
. The increment
方法返回错误代码而不是抛出异常。所以你的代码看起来像这样:
auto iter = fs::recursive_directory_iterator(dp, fs::directory_options::skip_permission_denied);
auto end_iter = fs::end(iter);
auto ec = std::error_code();
for (; iter != end_iter; iter.increment(ec))
{
if (ec)
{
continue;
}
// The rest of your loop code here...
}
我认为上面的内容看起来很合理,但绝对需要测试以确保不会出现一些奇怪的极端情况,导致无限循环或其他情况。其实我不太确定continue
甚至需要一些东西,但您可能想尝试一下。
最后,当你抓住一个filesystem_error
,你可以打印出e.path1.native()
此外e.what()
。我认为您已经基本上了解了该信息,因为您正在循环中打印路径。但在某些情况下它可能会提供更多信息。