我已经习惯了Delphi VCL框架,其中TStreams会在错误上抛出异常(例如找不到文件,磁盘已满).我正在移植一些代码来代替使用C++ STL,并且已被iostream捕获而不是默认情况下抛出异常,而是设置badbit/failbit标志.
两个问题......
a:为什么这样 - 对于从第一天开始就使用异常构建的语言,这似乎是一个奇怪的设计决策?
b:如何最好地避免这种情况?我可以按照我的预期生产可以抛出的垫片类,但这就像重新发明轮子一样.也许有一个BOOST库以更加理智的方式做到这一点?
我读过那个<fstream>早期的<exception>.忽略了例外fstream情况不是很有用的事实,我有以下问题:
可以使用该exceptions()方法在文件流上启用异常.
ifstream stream;
stream.exceptions(ifstream::failbit | ifstream::badbit);
stream.open(filename.c_str(), ios::binary);
Run Code Online (Sandbox Code Playgroud)
任何尝试打开不存在的文件,没有正确权限的文件或任何其他I/O问题都将导致异常.使用自信的编程风格非常好.该文件应该在那里并且可读.如果条件不满足,我们会得到例外.如果我不确定文件是否可以安全打开,我可以使用其他功能来测试它.
但现在假设我尝试读取缓冲区,如下所示:
char buffer[10];
stream.read(buffer, sizeof(buffer));
Run Code Online (Sandbox Code Playgroud)
如果流在填充缓冲区之前检测到文件结束,则流决定设置failbit,如果启用了异常,则会触发异常.为什么?这有什么意义?我本可以eof()在阅读后验证只是测试:
char buffer[10];
stream.read(buffer, sizeof(buffer));
if (stream.eof()) // or stream.gcount() != sizeof(buffer)
// handle eof myself
Run Code Online (Sandbox Code Playgroud)
这种设计选择使我无法在流上使用标准异常,并迫使我在权限或I/O错误上创建自己的异常处理.或者我错过了什么?有什么出路吗?例如,我可以轻松测试是否可以sizeof(buffer)在流之前读取字节数吗?