Java检测关闭流
我有一个由 OutputStream 和 InputStream 组成的通用套接字实现。
完成一些工作后,我将关闭 OutputStream。
完成此操作后,我的 InputStream 的 read() 方法会在无限长的时间内返回 -1,而不是像我预期的那样抛出异常。
我现在不确定最安全的路线,所以我有几个问题:
- 我可以安全地假设 -1 是唯一的吗? 当流关闭时返回?
- 有没有办法重新创建IO 当发生异常时 连接被强行断开?
- 我是否应该发送一个数据包来告诉我的 InputStream 它应该关闭,而不是前面的两种方法?
谢谢!
I have a general socket implementation consisting of an OutputStream and an InputStream.
After I do some work, I am closing the OutputStream.
When this is done, my InputStream's read() method returns -1 for an infinite amount of time, instead of throwing an exception like I had anticipated.
I am now unsure of the safest route to take, so I have a few of questions:
- Am I safe to assume that -1 is only
returned when the stream is closed? - Is there no way to recreate the IO
exception that occurs when the
connection is forcefully broken? - Should I send a packet that will tell my InputStream that it should close instead of the previous two methods?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(5)
我可以安全地假设 -1 仅在流关闭时返回吗?
是的。
您不应该假设这样的事情。您应该阅读 javadoc 并根据指定 API 的行为方式来实现。特别是如果您希望代码健壮(或如您所说的“安全”)。
话虽如此,这或多或少就是javadoc在本例中所说的内容。 (有人可能会质疑 EOF 和“流已关闭”不一定意味着同一件事......并且通过调用 InputStream.close()
或 Socket.close 来关闭流()
本地 会产生不同的效果,但是,这些都与您的用例没有直接关系。)
有没有办法重新创建强行断开连接时发生的IO异常?
不会。首先,通常不会首先抛出任何异常,因此通常没有什么可以“重新创建”。其次,原始异常中的信息(如果有的话)消失了。
我应该发送一个数据包来告诉我的 InputStream 它应该关闭,而不是前面的两种方法吗?
不。最好的方法是测试 read
调用的结果。无论如何,您都需要对其进行测试,因为您不能假设 read(byte[]) 方法(或其他方法)将返回您实际要求的字节数。
我认为在某些情况下抛出应用程序特定的异常是可以的。
但请记住一般原则,即异常不应用于正常的流量控制。
其他答案之一建议创建一个代理 InputStream 来抛出一些异常而不是返回 -1。
海事组织,这是一个坏主意。您最终会得到一个声称是 InputStream
的代理类,但违反了 read
方法的约定。如果代理被传递给需要正确实现的InputStream
,这可能会导致麻烦。
其次,InputStream
是一个抽象类
而不是接口
,因此Java的动态代理机制不起作用。 (例如,newProxyInstance
方法需要接口列表,而不是类。)
此外,关闭套接字中的输出流也会关闭套接字本身。
Socket 的 JavaDoc 是这么说的:
公共输出流 getOutputStream()
抛出 IOException 异常返回此套接字的输出流。 如果此套接字有关联的通道,则结果输出
流委托其所有操作
到频道。如果频道位于
非阻塞模式然后输出
流的写操作将抛出
IllegalBlockingModeException。关闭返回的OutputStream将关闭关联的套接字。 返回: 用于将字节写入此套接字的输出流。 投掷: IOException - 如果创建输出流时发生 I/O 错误
或者如果套接字未连接。
不确定这是否是您真正想要做的。
有没有办法重新创建强行断开连接时发生的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")。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
-1 是流结束时的预期行为。请参阅
InputStream.read ()
:当然,您仍然应该捕获
IOException
以防止意外事件。The -1 is the expected behavior at the end of a stream. See
InputStream.read()
:You should still catch
IOException
for unexpected events of course.