如果您使用标准 java IO,那么不会阻塞是一项棘手的任务。常见的答案是迁移到 NIO 或 netty。Netty 是更可取的选择。但是有时您别无选择,因此我建议您尝试我的解决方法:
public String readResponse(InputStream inStreamFromServer, int timeout) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(inStreamFromServer, Charsets.UTF_8));
char[] buffer = new char[8092];
boolean timeoutNotExceeded;
StringBuilder result = new StringBuilder();
final long startTime = System.nanoTime();
while ((timeoutNotExceeded = (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) < timeout))) {
if (reader.ready()) {
int charsRead = reader.read(buffer);
if (charsRead == -1) {
break;
}
result.append(buffer, 0, charsRead);
} else {
try {
Thread.sleep(timeout / 200);
} catch (InterruptedException ex) {
LOG.error("InterruptedException ex=", ex);
}
}
}
if (!timeoutNotExceeded) throw new SocketTimeoutException("Command timeout limit was exceeded: " + timeout);
return result.toString();
}
此解决方法不是灵丹妙药,但它具有一些重要功能:
- 不使用 readline()。这种方法对网络通信很危险,因为有些服务器不返回
LF/CR
符号,你的代码会卡住。当您从文件中读取时,这并不重要,您无论如何都会到达文件的末尾。
- 不使用
char symbol = (char) fr.read();
。这种方法比读取 char[] 慢
- 它具有超时功能,您可能会在慢速连接时中断通信