我有一个由OutputStream和InputStream组成的通用套接字实现。
在我完成一些工作之后,我正在关闭OutputStream。
完成后,我的InputStream的read()方法返回-1无限的时间,而不是像我预期的那样抛出异常。
我现在不确定最安全的路线,所以我有几个问题:
谢谢!
答案 0 :(得分:7)
-1是流末尾的预期行为。见InputStream.read()
:
从输入流中读取下一个数据字节。值字节作为int返回,范围为0到255. 如果没有字节可用,因为已到达流的末尾,则返回值-1。此方法将阻塞直到输入数据可用,检测到流的末尾,或抛出异常。
当然,你仍然应该抓住IOException
的意外事件。
答案 1 :(得分:2)
我可以安全地假设只在流关闭时返回-1吗?
是
你不应该假设这样的事情。您应该阅读javadoc并根据指定API的行为来实现。特别是如果你希望你的代码是健壮的(或者你说的那么“安全”。)
话虽如此, 或多或少是javadoc在这种情况下所说的。 (人们可以狡辩说EOF和“流已经关闭”并不一定意味着同样的事情......并且通过在本地调用InputStream.close()
或Socket.close()
来关闭流会有不同的效果。但是,这些都与你的用例没有直接关系。)
是否无法重新创建强制断开连接时发生的IO异常?
没有。首先,通常不会抛出任何异常,因此通常没有“重新创建”。其次,原始例外中的信息(如果有的话)已经消失。
我应该发送一个能告诉我的InputStream它应该关闭而不是前两种方法的数据包吗?
没有。最好的方法是测试read
调用的结果。无论如何你需要测试它,因为你不能假设read(byte[])
方法(或其他)会返回你实际要求的字节数。
我认为在某些情况下抛出特定于应用程序的异常 。
但请记住,不应将异常用于正常流量控制的一般原则。
其他一个答案建议创建一个抛出异常而不是返回-1的代理InputStream。
IMO,这是一个坏主意。您最终获得了声称是InputStream
的代理类,但违反了read
方法的合同。如果将代理传递给期望正确实现的InputStream
。,那么这可能会导致问题
其次,InputStream
是abstract class
而不是interface
,因此Java的动态代理机制不起作用。 (例如,newProxyInstance
方法需要接口列表,而不是类。)
答案 2 :(得分:0)
根据InputStream
javadoc,read()
返回:
数据的下一个字节,如果到达流的末尾则为-1。
因此,您可以安全地假设使用API中指定的内容而不是尝试重新创建异常,因为抛出的异常可能与实现有关。
答案 3 :(得分:0)
此外,关闭套接字中的输出流会关闭套接字本身。
这就是Socket的JavaDoc所说的:
public OutputStream getOutputStream() 抛出IOException
Returns an output stream for this socket. If this socket has an associated channel then the resulting output
stream委托其所有操作 到频道。如果频道在 非阻塞模式然后输出 stream的写操作会抛出 IllegalBlockingModeException。
Closing the returned OutputStream will close the associated socket. Returns: an output stream for writing bytes to this socket. Throws: IOException - if an I/O error occurs when creating the output stream
或者套接字未连接。
不确定这是你真正想做的事情。
答案 4 :(得分:-1)
是否无法重新创建强制断开连接时发生的IO异常?
我会回答这个问题。 InputStream只是一个接口。如果你真的想要实现在EOF上抛出异常,请提供你自己的小包装器,覆盖read()并在-1结果上抛出异常。
最简单(编码最少)的方法是使用动态代理:
InputStream pxy = (InputStream) java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
new Class[]{ InputStream.class },
new ThrowOnEOFProxy(obj));
其中ThrowOnEOFProxy将检查方法名称,调用它,如果结果为-1,则抛出IOException(“EOF”)。