read/block DataInputStream 提供以下 available() 的确切保证是什么

Exactly what read/block guarantees does DataInputStream provide following available()

我已阅读 java 文档和许多相关问题,但不确定以下内容是否能保证有效:

我在专用线程上有一个 DataInputStream,它从一个非常活跃的连接中持续读取少量已知字节大小的数据。我想在流变为非活动状态(即网络中断)时提醒用户,因此我实现了以下内容:

...
streamState = waitOnStreamForState(stream, 4);
int i = stream.readInt();
...

private static int
waitOnStreamForState(DataInputStream stream, int nBytes) throws IOException {
    return waitOnStream(stream, nBytes, STREAM_ACTIVITY_THRESHOLD, STREAM_POLL_INTERVAL)
            ? STREAM_STATE_ACTIVE 
            : STREAM_STATE_INACTIVE;

private static boolean
waitOnStream(DataInputStream stream, int nBytes, long timeout, long pollInterval) throws IOException {
    int timeWaitingForAvailable = 0;
    while( stream.available() < nBytes ){
        if( timeWaitingForAvailable >= timeout && timeout > 0 ){
            return false;
        }
        try{
            Thread.sleep(pollInterval);
        }catch( InterruptedException e ){
            Thread.currentThread().interrupt();
            return (stream.available() >= nBytes);
        }
        timeWaitingForAvailable += pollInterval;
    }
    return true;
}

available() 的文档说明:

Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream. The next caller might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes.

这是否意味着下一次读取(在 readInt() 内部)可能只读取 2 个字节,而后续读取完成检索 Integer 可能会阻塞?我意识到 readInt() 是流 'called next' 的一种方法,但我认为它必须循环读取调用直到它获得 4 个字节并且文档没有提到后续调用。在上面的示例中,即使 waitOnStreamForState(stream, 4) returns STREAM_STATE_ACTIVE,readInt() 调用是否仍然可能阻塞?

(是的,我意识到我的超时机制并不准确)

Does this mean it's possible the next read (inside readInt()) might only, for instance, read 2 bytes, and the subsequent read to finish retrieving the Integer could block?

这就是它所说的。但是至少下一个 read() 不会阻塞。

I realize readInt() is a method of the stream 'called next' but I presume it has to loop on a read call until it gets 4 bytes and the docs don't mention subsequent calls. In the above example is it possible that the readInt() call could still block even if waitOnStreamForState(stream, 4) returns STREAM_STATE_ACTIVE?

这就是它所说的。

例如,考虑 SSL。您可以知道有可用数据,但如果不实际解密就无法知道有多少,因此 JSSE 实现可以自由地:

  • 总是 return 来自 available() 的 0(这是它过去所做的)
  • 总是return 1 如果底层套接字的输入流有available() > 0,否则为零
  • return 底层套接字输入流的 available() 值,如果实际明文数据较少,则依靠此措辞使其摆脱困境。 (但是,如果密码数据完全由握手消息或警报组成,则正确的值可能仍为零。)

但是你不需要这些。您只需要一个读取超时,通过 Socket.setSoTimeout() 设置,以及 SocketTimeoutExceptioncatchavailable() 的正确用法几乎没有:在我看来,随着时间的推移越来越少。你当然应该不要浪费时间打电话给sleep()