我有一些代码使用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的理解是错误的?)
答案 0 :(得分:1)
std::filebuf
似乎根本没有任何形式的错误处理/报告。那太可悲了。我的意思是,为什么不?
因此,要使用它,唯一的选择就是退回到旧的errno
上,并且由于cppreference上的条目根本没有提及,我想您不能确实依靠它(尽管我确信实际上可以奏效)。
因此,std::ifstream
必须走的路,如果您可以通过那庞大且有些晦涩的清单来说明哪个异常位会做什么的话。当然,如果以这种方式进行操作,就可以控制是否引发异常。
同样,当出现问题时,也没有明显的方法来检索任何类型的错误代码,因此再次提醒您,如果您想尝试向用户展示任何有意义的错误消息(或为了技术支持,也许),那么errno
是镇上唯一的游戏。
这一切只会导致“出了点问题”错误消息的泛滥。 。