8

我在使用 boost::filesystem::exists 时遇到了一些奇怪的情况。如果您尝试检查未准备好或没有媒体的驱动器上是否存在文件,则会引发 basic_filesystem_error。就我所关心的 bfs::exists 的大多数用途而言,如果驱动器尚未准备好,则意味着该文件不存在。

我可以用 try-catch 包装我的调用以正确处理这种情况,但是它变得有点麻烦并且使代码有点笨拙。更糟糕的是,这意味着我正在使用 basic_filesystem_error 的特殊情况进行流量控制,这意味着如果出现该异常的其他原因,我将无法再正确处理它。

出现这种情况的一般情况是,如果我尝试检查 CD 或 DVD 驱动器上是否存在文件。我的代码曾经是:

if( bfs::exists( myFilePath ) )
{
...
}

变成:

bool fileExists( false );
try
{
   fileExists = bfs::exists( myFilePath );
}
catch( bfs::basic_filesystem_error<bfs::path> e )
{
   fileExists = false;
}
if( fileExists )
{
...
}

我并不太喜欢在我现有的代码库中到处进行这种更改。

我正在考虑在某个地方创建一个单独的函数来包装 try-catch 并用它替换我的 bfs::exist 调用,但我仍然不满意以这种方式使用 try-catch 是个好主意。似乎我正在为错过更重要和相关的特殊情况敞开大门。

我知道您可以为该函数的非抛出版本重新编译 boost,但我认为这并不能真正避免我的异常处理问题。

以前有没有人遇到过可移动媒体驱动器的这个问题,如果有,你是如何克服的?

4

3 回答 3

5

根据文档,exists(file_status s) 返回status_known(s) && s.type() != file_not_found”。

该文件还指出

file_status如果底层文件系统在[ ]属性判断过程中报错:

  • 如果错误表示p无法解决,就好像通过 POSIX 错误ENOENT[ie, not found] ... return file_status(not_found_flag)

在我看来,抛出异常不是预期的行为。(当您创建status对象时,它的状态是已知的,并且该状态是not_found)。

但是,文档继续说:

[注:此行为的作用是区分知道p不存在和无法确定p. 这种区别对用户很重要。——尾注]

这意味着该库确实打算区分“文件不存在”和“我无法确定该文件不存在”。您可能希望联系图书馆的作者以获得更清晰的声明。

但是,测试文件是否存在是一种竞争条件:当操作系统查看时,该文件可能已经存在,但不能保证它会继续存在;同样,该文件在操作系统查看时可能不存在,但不能保证它会继续不存在。 竞争条件可能具有安全隐患

相反,打开文件,然后查看它的属性是什么。文件打开后,操作系统会对哪些会更改哪些不会更改做出某些保证。

于 2009-06-30T22:13:15.787 回答
2

这是一个错误,可能与:

https://svn.boost.org/trac/boost/ticket/2725

您使用的是最新的 Boost 版本吗?如果是,请在此处报告另一个错误。看:

http://www.boost.org/support/bugs.html

于 2009-06-30T21:05:35.830 回答
0

我最终通过重新编译 boost 消除了这种不安,并将更新的文件系统 .lib 文件重新链接到我的项目

于 2020-03-26T07:53:08.293 回答