Java InputStream+;BufferedInputStream吞噬异常
我有一个问题,当抛出异常时,我的程序没有按预期结束。我跟踪到了InputStream和BufferedInputStream的组合,它们吞并了异常。以下代码演示了该问题:Java InputStream+;BufferedInputStream吞噬异常,java,inputstream,bufferedinputstream,Java,Inputstream,Bufferedinputstream,我有一个问题,当抛出异常时,我的程序没有按预期结束。我跟踪到了InputStream和BufferedInputStream的组合,它们吞并了异常。以下代码演示了该问题: import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; public class Test { public static void main(String[] args) throws I
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws IOException {
try (InputStream stream = new BufferedInputStream(new MyStream())) {
int x = stream.read();
while (x != -1) {
System.out.println(x);
x = stream.read();
}
}
}
static class MyStream extends InputStream {
int i = 0;
@Override
public int read() throws IOException {
i = i + 1;
if (i == 5) {
throw new IOException("i == 5");
}
if (i > 10) {
return -1;
}
return i;
}
}
}
这将产生输出
1.
2.
3.
4.
6.
7.
8.
9
十,
如果删除了BufferedInputStream,则当i==5时会引发异常
我追踪到了InputStream代码。如果读取多个字节,InputStream将只传播第一个字节的IOException,而不是后续字节。BufferedInputStream将读取行为更改为一次读取多个字节,因此InputStream捕获并丢弃IOException
这里的正确行为是什么
“一旦发生IOException,就永远是IOException”,即MyStream需要记住它抛出了IOException,然后在任何后续调用中再次抛出,这是一条规则吗
其他备选方案:
- 抛出InputStream不会捕获的未检查异常。我认为在扩展InputStream时无法抛出不同的已检查异常
- 还要重写多字节读取方法,以便它不会捕获IOException。然而,如果它再次被其他输入流包装,它似乎也会受到同样的问题的影响
我感谢您的指导。目前,我认为未经检查的异常是我最好的选择。
如果读取多个字节,InputStream将只为第一个字节传播IOException,
您是说“BufferedInputStream”吗?否则我会有点困惑您的实际测试结果是什么。@markspaceNo,InputStream是正确的,请参见说明:。BufferedInputStream调用该方法。因此@Tom是正确的,这是InputStream
的记录行为,或者至少是它的默认实现。我会告诉你吃I/O错误,像这样是很奇怪的,但它就是这样做的。文档给了你一个提示,你可以子类化InputStream
,如果需要的话,提供你自己的更好的实现。现在我想起来了,这就是我使用实际类InputStream
的全部目的,就是子类化它。所有其他输入流都是子类:FileInputStream
、SocketInputStream
、ObjectInputStream
等。它是一个设计用来替换的基类。如果我用更好的实现对其进行子类化,则仍有人可以围绕它包装另一个InputStream,这将再次吞噬异常。我可以看出这是有文档记录的行为,我只是不确定在实现InputStream时使用它的最佳方式。