我正在尝试编写一段解锁代码来从
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.