Java PipedInputStream available()方法返回值

我正在尝试编写一段解锁代码来从
PipedInputStream读取.它基本上检查在调用阻塞读取API之前是否有任何要读取的内容:

int n = 0;
if ((n = pipedInputStream_.available()) > 0) {
     pipedInputStream_.read(...)
}

阅读java API doc我无法确定该检查应该是什么,因为可能的值为零(表示没有数据,或关闭/中断流)或大于零.那么调用者如何知道是否有任何东西要读?

“Returns the number of bytes that can be read from this input stream without blocking, or 0 if this input stream has been closed by invoking its close() method, or if the pipe is unconnected, or broken.”

看看源,似乎唯一的值是零或大于零.

public synchronized int available() throws IOException {
    if(in < 0)
        return 0;
    else if(in == out)
        return buffer.length;
    else if (in > out)
        return in - out;
    else
        return in + buffer.length - out;
}

最佳答案 如果available()返回零,则目前没有可供读取的字节.根据您引用的文档,可能有以下原因:

>管道关闭了.
>管子坏了.
>所有先前可用的输入(如果有)已被消耗.

来自available()的零返回值可能意味着发生了错误,这意味着您将来永远无法通过管道读取更多数据,但您无法在此确定,因为零可能表示上面的第三个条件,其中阻塞InputStream#read()可能最终产生更多数据,相应的OutputStream端将​​推送通过管道.

我没有看到可以使用available()轮询PipedInputStream,直到有更多的数据可用,因为你永远无法区分上面(第一个和第二个)的终端案例和读者比饥饿者更饥饿作家.像许多流接口一样,在这里你也必须尝试使用​​并准备好失败.那是陷阱; InputStream#read()将阻塞,但是直到您尝试阻止尝试读取才能识别出不再有输入.

将您的消费操作建立在available()上是不可行的.如果它返回一个正数,那么有一些东西需要阅读,但当然即使现在可用的东西也可能不足以满足你的消费者.如果您提交线程以阻塞方式使用InputStream并使用available()跳过轮询,您会发现应用程序更易于管理.让InputStream#read()成为你唯一的oracle.

点赞