目前,我依靠该ObjectInputStream.available()
方法来告诉我流中还剩下多少字节。原因——我正在对某些处理流的函数编写一些单元/集成测试,我只是想确保该available()
方法在完成后返回 0。
不幸的是,在测试失败时(即,我已经在流中发送了大约 8 个字节),我的断言 foravailable() == 0
在它应该是假的时候是真的。它应该显示 >0 或 8 个字节!
我知道该available()
方法在经典上是不可靠的,但我认为它至少会显示 > 0!
有没有更可靠的方法来检查流是否为空(毕竟这是我的主要目标)?也许在 Apache IO 域或其他一些库中?
有谁知道为什么这种available()
方法非常不可靠?有什么意义呢?或者,是否有特定的、正确的使用方法?
更新:
所以,正如你们中的许多人可以从评论中看到的那样,我面临的主要问题是,在流的一端,我发送了一定数量的字节,但在另一端,并不是所有的字节都到达了!
具体来说,我在一端发送 205498 字节,而在另一端只收到 204988,始终如一。我在套接字中的线程之间控制此操作的双方,但这应该没关系。
这是我为收集所有字节而编写的代码。
public static int copyStream(InputStream readFrom, OutputStream writeTo, int bytesToRead)
throws IOException {
int bytesReadTotal = 0, bytesRead = 0, countTries = 0, available = 0, bufferSize = 1024 * 4;
byte[] buffer = new byte[bufferSize];
while (bytesReadTotal < bytesToRead) {
if (bytesToRead - bytesReadTotal < bufferSize)
buffer = new byte[bytesToRead - bytesReadTotal];
if (0 < (available = readFrom.available())) {
bytesReadTotal += (bytesRead = readFrom.read(buffer));
writeTo.write(buffer, 0, bytesRead);
countTries = 0;
} else if (countTries < 1000)
try {
countTries++;
Thread.sleep(1L);
} catch (InterruptedException ignore) {}
else
break;
}
return bytesReadTotal;
}
我把 countTries 变量放在那里只是为了看看会发生什么。即使没有 countTires,它也会在到达 BytesToRead 之前永远阻塞。
什么会导致流突然无限期地阻塞?我知道在另一端它完全发送字节(因为它实际上使用了相同的方法,我看到它最终完成了完整的 BytesToRead 匹配 bytesReadTotal 的功能。但接收器没有。事实上,当我看看数组,它们也完全匹配到最后。
更新2
我注意到,当我writeTo.flush()
在 copyStream 方法的末尾添加 a 时,它似乎又可以工作了。嗯..为什么在这种情况下冲洗如此重要。即,为什么不使用它会导致流永久阻塞?