如何立即关闭 InputStream?
How to close InputStream immediately?
有一个无限的输入流,我通过以下简单的代码行读取了传入的消息:
InputStream inputStream = response.getBody();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
while ((event = reader.readLine()) != null) {
// do the work
}
}
System.out.println("Connection closed");
一切都很好。但是我希望能够在一定时间内没有新消息时断开连接。
第一个问题是 readLine
方法会阻塞执行,直到收到下一条消息。这就是我想避免的。我发现 CloasableReader 的 - Bufferedreader 的包装器允许从外部中断 readLine
。所以我只是将 BufferedReader 替换为 CloasableReader 和 voalá - 我退出了 while 循环。但是带有 "Connection closed" 消息的行仍然没有被执行。
我稍微修改了一下代码...
InputStream inputStream = response.getBody();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((event = reader.readLine()) != null) {
// do the work
}
} finally {
if (reader != null) {
reader.close();
}
}
System.out.println("Connection closed");
...并意识到实际上 close
方法也会卡住,等待下一条消息接收。因为 Guava 的 TimeLimiter::callWithTimeout
方法对我不起作用。实际上它工作正常(包装上面示例中标记为 "do the work" 的代码)但我不能离开 try-catch-finaly 块。
内部 BufferedReader::close
调用 InputStreamReader::close
,后者又调用 InputStream::close
,这就是问题所在。我只是在等待,并将永远这样做。
我不知道现在该怎么办。如何强制关闭流?
您的问题看起来与 非常相似。您可以尝试在那里找到有关 callWithTimeout
.
的线索
如果您的输入流来自某个套接字,您可以尝试不带 callWithTimeout
的版本并添加 Socket.setSoTimeout
,因此在指定次数后从 InputStream 读取时会抛出 java.net.SocketTimeoutException
毫秒。
编辑: 由于您使用的是 ClientHttpResponse
,您可以像这样设置读取和连接超时
@Component
public static class RestTemplateInitializer implements ApplicationListener<ApplicationReadyEvent> {
public static HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
@Override
public void onApplicationEvent(ApplicationReadyEvent e) {
clientHttpRequestFactory.setConnectTimeout(10000);
clientHttpRequestFactory.setReadTimeout(10000);
}
}
有一个无限的输入流,我通过以下简单的代码行读取了传入的消息:
InputStream inputStream = response.getBody();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
while ((event = reader.readLine()) != null) {
// do the work
}
}
System.out.println("Connection closed");
一切都很好。但是我希望能够在一定时间内没有新消息时断开连接。
第一个问题是 readLine
方法会阻塞执行,直到收到下一条消息。这就是我想避免的。我发现 CloasableReader 的 readLine
。所以我只是将 BufferedReader 替换为 CloasableReader 和 voalá - 我退出了 while 循环。但是带有 "Connection closed" 消息的行仍然没有被执行。
我稍微修改了一下代码...
InputStream inputStream = response.getBody();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((event = reader.readLine()) != null) {
// do the work
}
} finally {
if (reader != null) {
reader.close();
}
}
System.out.println("Connection closed");
...并意识到实际上 close
方法也会卡住,等待下一条消息接收。因为 Guava 的 TimeLimiter::callWithTimeout
方法对我不起作用。实际上它工作正常(包装上面示例中标记为 "do the work" 的代码)但我不能离开 try-catch-finaly 块。
内部 BufferedReader::close
调用 InputStreamReader::close
,后者又调用 InputStream::close
,这就是问题所在。我只是在等待,并将永远这样做。
我不知道现在该怎么办。如何强制关闭流?
您的问题看起来与 callWithTimeout
.
如果您的输入流来自某个套接字,您可以尝试不带 callWithTimeout
的版本并添加 Socket.setSoTimeout
,因此在指定次数后从 InputStream 读取时会抛出 java.net.SocketTimeoutException
毫秒。
编辑: 由于您使用的是 ClientHttpResponse
,您可以像这样设置读取和连接超时
@Component
public static class RestTemplateInitializer implements ApplicationListener<ApplicationReadyEvent> {
public static HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
@Override
public void onApplicationEvent(ApplicationReadyEvent e) {
clientHttpRequestFactory.setConnectTimeout(10000);
clientHttpRequestFactory.setReadTimeout(10000);
}
}