使用 std::filebuf 时检测基础文件的完整性丢失?

Detect loss of integrity of the underlying file when using std::filebuf?

我有一些代码使用 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() 是这样说的:

If an internal operation throws an exception, it is caught and badbit is set. If exceptions() is set for badbit, the exception is rethrown.

由于 badbit 用于表示底层文件因某种原因损坏(可能 OS 无法再访问该文件),因此 std::ifstream 代码片段将通过跳出循环来处理这种可能性(good() 将 return false)。

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

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

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

所以,要使用它,唯一的选择就是回到好的旧 errno,并且由于 cppreference 的条目根本没有提到这一点,我想你可以不是真的依赖它(尽管我确信它在实践中是有效的)。

因此,std::ifstream 必须是要走的路,如果您可以通过那个庞大且有点模糊的异常位做什么列表。当然,如果你这样做,你可以控制是否抛出异常。

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

这一切只会导致 'Something went wrong' 错误消息的激增。嗯。