它建立了以下代码,似乎运作良好:
void pipe(InputStream, OutputStream os) {
try {
try {
byte[] buf = new byte[1024*16];
int len, available = is.available();
while ((len = is.read(buf, 0, available > 0 ? available : 1)) != -1) {
os.write(buf, 0, len);
available = is.available();
if(available <= 0)
os.flush();
}
} finally {
try {
os.flush();
} finally {
os.close();
}
}
} finally {
is.close();
}
}
在过去,我发现如果我调用is.read(buf)
,那么,即使数据可用,它也会阻止等待更多数据,直到缓冲区已满。这是一个用于TCP数据的echo服务器,所以我的要求是在新数据到达后立即进行刷新。
我的第一个解决方案是一次一个低效is.read()
。后来,当这还不够好时,我正在查看可用的方法并找到is.available()
。 API声明:
单个读取或跳过这么多字节不会阻塞。
所以我现在有一个非常好的解决方案,但对我来说一件坏事就是我如何处理is.available() == 0
的情况。在这种情况下,我只是读取一个字节作为等待新数据可用的方式。
将数据从InputStream
传输到OutputStream
的推荐方法是什么?在数据到达时立即刷新?以上代码是否真的是正确的方式,或者我应该更改它,还是使用一些全新的代码?也许我应该使用一些较新的异步例程,或者可能有一个内置的Java方法呢?
答案 0 :(得分:2)
在过去,我发现如果我调用is.read(buf),那么,即使数据可用,它也会阻止等待更多数据,直到缓冲区已满。
不,你没有。 TCP无法正常工作;套接字无法正常工作;和Java套接字不起作用。你错了。
这比你想象的要简单得多:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
out.close();
in.close();
套接字输入/输出流没有缓冲,因此一旦读取它就会写入所有内容。
在这种情况下或几乎在任何情况下调用available()都是完全浪费时间。
这也是将任何类型的输入流复制到Java中任何类型的输出流的方法。
如果您想要非阻止代码,请使用NIO。但我不认为你真的这么做。