gpt4 book ai didi

java - Java InputStream 到 OutputStream 的非阻塞回显

转载 作者:可可西里 更新时间:2023-11-01 02:41:14 24 4
gpt4 key购买 nike

它已经建立了以下代码,看起来运行良好:

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 数据的回显服务器,所以我的要求是在新数据到达时立即刷新。

我的第一个解决方案是效率低下的一次一个 is.read()。后来,当这还不够好时,我查看了可用的方法并找到了 is.available()。 API 声明:

A single read or skip of this many bytes will not block.

所以我现在有一个很好的解决方案,但对我来说不好的一件事是我如何处理 is.available() == 0 的情况。在这种情况下,我只是读取一个字节作为等待新数据可用的一种方式。


将数据从 InputStream 传输到 OutputStream 并在数据到达时立即刷新的推荐方法是什么?上面的代码真的是正确的方法吗,或者我应该改变它,还是使用一些全新的代码?或许我应该使用一些较新的异步例程,或者可能有一个内置的 Java 方法来实现?

最佳答案

In the past, I found that if I call is.read(buf), then, even if data was available, it would block waiting for more data until the buffer was full.

不,你没有。 TCP 不是这样工作的;套接字不能那样工作;而 Java 套接字不是那样工作的。你错了。

它比你想象的要简单得多:

while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
out.close();
in.close();

套接字输入/输出流上没有缓冲,因此这将在读取后立即写入所有读取的内容。

在这种情况下,或者实际上在几乎任何情况下,调用 available() 完全是浪费时间。

这也是在 Java 中将任何类型的输入流复制到任何类型的输出流的方法。

如果你想要非阻塞代码,使用 NIO。但我不认为你真的这样做。

关于java - Java InputStream 到 OutputStream 的非阻塞回显,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15577564/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com