2

我有一些用于std::ifstream从文件中读取的代码,但不使用std::ifstream. 它本质上是这样的:

std::ifstream in;
in.open("example.txt", std::ios_base::in | std::ios_base::binary);
if (in.is_open()) {
    while (in.good()) {
        in.read(buffer, buffer_size);
        auto num_bytes = in.gcount();
        /* do stuff with the bytes */
    }
    in.close();
}

由于我直接处理文件中的原始字节,因此它似乎更适合使用std::filebuf而不是std::ifstream

std::filebuf in;
if (in.open("example.txt", std::ios_base::in | std::ios_base::binary) != nullptr) {
    while (true) {
        auto num_bytes = in.sgetn(buffer, buffer_size);
        /* do stuff with the bytes */
        if (num_bytes < buffer_size) break;
    }
    in.close();
}

从表面上看,这两个代码片段可能实现了相同的结果。然而,在检查 C++ 参考资料后,std::basic_istream::read()说:

如果内部操作抛出异常,则会被捕获并设置 badbit。如果为 badbit 设置了 exceptions(),则重新抛出异常。

由于badbit用于指示底层文件由于某种原因已损坏(可能操作系统无法再访问该文件),因此std::ifstream代码片段似乎将通过跳出循环来处理这种可能性(good()将返回false)。

但是,std::basic_streambuf::sgetn()并没有说明底层文件变得不可访问的可能性。它也没有提到抛出任何异常的可能性(但它没有标记为noexcept)。

有没有办法在使用std::filebuf时正确处理文件过早无法访问(即尚未 EOF)的情况?(或者,我对文件 I/O 的理解是错误的?)

4

1 回答 1

1

std::filebuf似乎根本没有任何形式的错误处理/报告。这简直太可悲了。我的意思是,为什么不呢?

因此,要使用它,唯一的选择是使用 good old ,并且由于cppreferenceerrno的条目根本没有提到这一点,我想你不能真正依赖它(尽管我确信,实际上,它有效)。

因此,std::ifstream如果您可以通过那个庞大且有点晦涩的列表来说明哪个异常位做什么,那么必须是要走的路。当然,如果你以这种方式做事,你就可以控制是否抛出异常。

同样,当出现问题时,没有明显的方法可以检索任何类型的错误代码,所以再一次,如果您想尝试向您的用户呈现任何类型的有意义的错误消息(或者可能是为了技术支持的利益),然后errno是镇上唯一的游戏。

这一切只会导致“出现问题”错误消息的泛滥。玉。

于 2018-07-14T19:42:16.200 回答