Java 对流套接字的原子非阻塞写入
如果我在一个由通道支持的非阻塞套接字上获取,并进行写抛出,那么是否保证所有字节数组都被写入,或者没有写入Java 对流套接字的原子非阻塞写入,java,sockets,nio,nonblocking,Java,Sockets,Nio,Nonblocking,如果我在一个由通道支持的非阻塞套接字上获取,并进行写抛出,那么是否保证所有字节数组都被写入,或者没有写入 我在上面链接的文档中找不到明确的答案。简短回答:不要假设或,也不要要求任何特定的行为来实现代码的正确功能 长话短说:没有办法笼统地确定;如果抛出IOException,则它可能发生在操作的任何一点上,并且随后应假定流的状态为未定义 尽管javadoc的非法封锁例外声明 Unchecked exception thrown when a blocking-mode-specific opera
我在上面链接的文档中找不到明确的答案。简短回答:不要假设或,也不要要求任何特定的行为来实现代码的正确功能 长话短说:没有办法笼统地确定;如果抛出IOException,则它可能发生在操作的任何一点上,并且随后应假定流的状态为未定义 尽管javadoc的非法封锁例外声明
Unchecked exception thrown when a blocking-mode-specific operation
is invoked upon a channel in the incorrect blocking mode
虽然措辞意味着在任何工作实际发生之前对其进行检查,但在实际执行之后检查非法操作是没有意义的,问题是异常可能发生在一组相关对象中的某个位置,因此,在抛出异常之前,无法知道这些对象的状态是否发生了变化
最明智的选择是不尝试该操作,或者如果无法避免,则不假设异常发生后流/通道的状态
然而,我会假设没有实际写入字节,因为只有在实际写入数据之前进行检查才有意义——但是——这实际上是SocketChannelImpl中的一个实现细节。您可以挖掘src.zip中未提供的sun.nio.ch.socketchannellimpl的源代码,以实际检查实现;但这只能为具体的实现提供明确的证据。请参阅Channels.newOutputStream的Javadoc:
如果在底层通道处于非阻塞模式时调用,则结果流的写入方法将抛出IllegalBlockingModeException
在尝试任何写入之前,将检查该模式。没有其他的实现是有意义的。如果写作是可能的,为什么会有例外呢?下定决心吧“不要假设”或“我会假设”?异常不是由您提到的类引发的。好的,因此答案是非阻塞通道的OutputStream不可写,完全停止,无论当前写入操作是否会填充输出缓冲区,因此任何写入尝试都会引发非法BlockingModeException。因此,您可以将通道切换到阻塞模式并使用流,然后将其切换到非阻塞模式并使用非阻塞nio操作,但不能同时执行这两种操作。