boost::filesystem::exists 真的应该为没有媒体的可移动媒体设备抛出异常吗?

发布于 2024-07-25 10:05:43 字数 916 浏览 13 评论 0 原文

我在使用 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,但我认为这并不能真正避免我的异常处理问题。

以前有人在使用可移动媒体驱动器时遇到过这个问题吗?如果有的话,您是如何克服的?

I've run into a bit of an odd circumstance while using boost::filesystem::exists. If you attempt to check for the existance of a file on a drive that isn't ready or has no media in it, it throws a basic_filesystem_error. As far as I'm concerned for most all uses of bfs::exists, if a drive isn't ready it means the file doesn't exist.

I can wrap my calls with a try-catch to properly handle this condition, however it becomes a bit cumbersome and makes the code a bit clunky. And worse, it means I'm using a special case of basic_filesystem_error for flow control, which means if a different reason for that exception were to arrise, I wouldn't be handling it properly anymore.

The general case where this comes up is if I attempt to check if a file exists on a CD or DVD drive. My code which used to be:

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

Becomes:

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

I'm not overly enamored with the thought of making this change all over the place in my existing code base.

I'm considering making a seperate function somewhere that wrapps up the try-catch and replacing my bfs::exist calls with that, but I'm still not satisfied that using the try-catch in that manner is a good idea. It seems like I'm opening the door for missing more important and relevant exceptional conditions.

I'm aware that you can recompile boost for a non-throwing version of the function, but I don't think that really avoids my exception handling concerns.

Has anyone run into this problem with removable media drives before, and if so how did you overcome it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

春风十里 2024-08-01 10:05:44

这是一个错误,可能与以下内容有关:

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

您使用的是最新的 Boost 版本吗?
如果是,请在那里报告另一个错误。 请参阅:

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

It's a bug, probably related to:

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

Are you using the latest Boost version?
If yes, report another bug there. See:

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

哭了丶谁疼 2024-08-01 10:05:44

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

I removed this upset finally by recompiling boost, and relink the updated filesystem .lib files to my project

小草泠泠 2024-08-01 10:05:43

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

文档还指出 :

如果底层文件系统在 [file_status] 属性确定期间报告错误:

  • 如果错误表明 p 无法解析,就像 POSIX 错误一样 ENOENT [即未找到] ... return file_status(not_found_flag )

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

然而,文档继续说:

[注意:此行为的效果是区分知道 p 不存在和无法确定 p 的状态。 这种区别对于用户来说很重要。 --注结束]

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

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

相反,打开该文件,然后查看其属性。 文件打开后,操作系统会对哪些内容会发生变化、哪些不会发生变化做出一定的保证。

According to the documentation, exists(file_status s) returns "status_known(s) && s.type() != file_not_found".

The documentation also states that:

If the underlying file system reports an error during [file_status] attribute determination:

  • If the error indicating that p could not be resolved, as if by POSIX errors ENOENT [i.e., not found] ... return file_status(not_found_flag).

It seems to me that throwing an exception is not the intended behavior. (when you create the status object its status is known, and that status is not_found).

However, the documentation continues by saying:

[Note: The effect of this behavior is to distinguish between knowing that p does not exist, and not being able to determine the status of p. This distinction is important to users. --end note]

Which implies that the library does intend to make a distinction between "file does not exist" and "I can't determine that file does not exist." You may wish to contact the library's authors for a clearer statement.

However, testing for the existence of a file is a race condition: the file may have existed when the OS looked, but there is no guarantee that it will continue to exist; likewise, the file may not have existed when the OS looked, but there is no guarantee that it will continue not existing. The race condition can have security implications.

Instead, open the file and then see what its attributes are. Once the file is open, the OS makes certain guarantees about what will change and what won't.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文