简体   繁体   English

原子无阻塞写入流套接字

[英]Atomic non-blocking writes to stream sockets

If I write(byte[]) to an OutputStream obtained from Socket.getOutputStream() on a non-blocking Socket backed by a Channel , and write() throws IllegalBlockingModeException , is it guaranteed that all the byte-array is written or none of it is? 如果我write(byte[]) Channel支持的非阻塞SocketSocket.getOutputStream()获得OutputStream ,并且write()抛出IllegalBlockingModeException ,是否可以保证所有字节数组都已写入或没有写入它是?

I can't find a clear answer in the docs linked above. 我在上面链接的文档中找不到明确的答案。

See the Javadoc of Channels.newOutputStream(): 请参见Channels.newOutputStream():的Javadoc Channels.newOutputStream():

The write methods of the resulting stream will throw an IllegalBlockingModeException if invoked while the underlying channel is in non-blocking mode. 如果在基础通道处于非阻塞模式下调用,则结果流的write方法将抛出IllegalBlockingModeException。

The mode is checked before any write is attempted. 在尝试任何写入之前,将检查该模式。 No other implementation would make sense. 没有其他实现会有意义。 And if writing was possible why would there be an exception at all? 如果可以写作,那为什么还要例外呢?

Short answer: Don't assume either or and do not require any specific behavior for the correct function of your code. 简短的答案:对于您的代码的正确功能,不要假设或且不需要任何特定的行为。

Long answer: There is no way to generically tell for sure; 长答案:没有一种方法可以一概而论。 if an IOException is thrown, it can occur at any point of the operation and the state of the stream should be assumed as "undefined" afterwards. 如果抛出IOException,则它可以在操作的任何时刻发生,并且之后应将流的状态假定为“未定义”。

Despite the javadoc of IllegalBlockingException stating 尽管IllegalBlockingException的javadoc声明

Unchecked exception thrown when a blocking-mode-specific operation
is invoked upon a channel in the incorrect blocking mode

and while the wording implies that it is checked before any work actually takes place (it wouldn't make sense to check for an illegal operation after actually performing it), the problem is the exception is probably occuring somewhere in a set of related objects, so there is no way of knowing if any of these objects states has changed before the exception was thrown. 尽管该措辞暗示着在实际进行任何工作之前都要对其进行检查(在实际执行之后检查非法操作是没有意义的),但问题是例外可能发生在一组相关对象的某处,因此无法知道在引发异常之前这些对象状态是否已更改。

The sanest option is to not attempt the operation, or if it can't be avoided, not to assume anything in particular about the state of the stream/channel after the exception occured. 最明智的选择是不尝试操作,或者,如果无法避免,则不要对异常发生后的流/通道状态做出特别的假设。

I would however assume hat no bytes will have been actually written, because the condition makes only sense to check before actually writing data - but - thats actually an implementation detail in SocketChannelImpl. 但是,我假定实际上不会写入任何字节,因为该条件仅在实际写入数据之前检查才有意义-但这实际上是SocketChannelImpl中的一个实现细节。 You could dig for the source code of sun.nio.ch.SocketChannelImpl (its not provided in src.zip) to actually check the implementation; 您可以挖掘sun.nio.ch.SocketChannelImpl的源代码(src.zip中未提供)来实际检查实现; but that would only give definite proof for that specific implementation. 但这只能为该特定实现提供确定的证据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM