有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何立即关闭InputStream?

有一个无限的输入流,我用以下简单的代码行阅读输入消息:

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方法会在下一条消息接收之前阻止执行。这就是我想要避免的。我在Bufferedreader上找到了this implementationCloasableReader-wrapper,它允许从外部中断readLine。所以我用CloasableReadervoalá替换了BufferedReader——我退出了while循环。但带有“连接已关闭”消息的行仍然没有执行

我把代码改了一点

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方法也会阻塞等待,直到下一个消息接收。因为番石榴的TimeLimiter::callWithTimeout方法对我不起作用。实际上,它工作得很好(在上面的示例中包装标记为“do the work”的代码),但我不能离开try-catch finally块

在内部BufferedReader::close调用InputStreamReader::close,它调用InputStream::close,这就是问题所在。我只是在等待,并将永远这样做

我不知道现在该怎么办。如何强制关闭流


共 (1) 个答案

  1. # 1 楼答案

    你的问题看起来很像this one。你可以在那里找到关于callWithTimeout的线索

    如果您的输入流来自某个套接字,您可以尝试不使用callWithTimeout的版本,并添加Socket.setSoTimeout,因此在指定的毫秒数之后从InputStream读取时,它将抛出java.net.SocketTimeoutException

    EDIT:因为您使用的是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);
            }
    
    
        }