使用 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' 错误消息的激增。嗯。
我有一些代码使用 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' 错误消息的激增。嗯。