如何杀死BufferedInputStream .read()调用

时间:2012-01-27 23:35:07

标签: java download inputstream httpurlconnection bufferedinputstream

我正在编写一个程序来从服务器下载非常大的文件(~2GB)。我已经编写了程序,可以恢复部分完成的下载,

为了模拟一个糟糕的互联网连接,我一直在下载中途时将我的以太网线从我的路由器中拔出。不幸的是,这导致我的程序挂起以下调用: while((bytesRead = in.read(data)) > 0)

(其中bytesRead是int,in是从HttpURLConnection构建的BufferedInputStream,数据是字节数组)。

我试图通过在另一个线程上调用in.close()来“中断”调用,但是在恢复互联网连接之前它没有任何效果(此时会抛出异常)。

有什么方法可以防止被切断的互联网连接冻结我的程序?

3 个答案:

答案 0 :(得分:2)

我找到的唯一可靠方法是将Socket实例化为InterruptibleChannel,并在卡住的IO线程上执行中断。 (顺便说一句,你不必使用InterruptibleChannels的异步NIO调用,阻止I / O工作正常,你只是有一个非常好的和统一的方式来解决卡住的交换)

虽然看起来URLConnection不允许您连接自定义套接字工厂。

也许你应该从Apache调查HttpClient

修改

以下是创建可中断套接字的方法。

import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.SocketChannel;

final SocketAddress remoteAddr =
    new InetSocketAddress(
        serverAddress,
        servicePort
    );

final SocketChannel socketChannel = SocketChannel.open( );

socketChannel.connect( remoteAddr );

// Here java.io.Socket is obtained
Socket socket = socketChannel.socket( );

我没有HttpClient示例,但我知道您可以自定义套接字初始化。

答案 1 :(得分:1)

.setReadTimeout(int timeout)上有URLConnection吗?

- 编辑

请参阅@DNA的答案以获得一个简洁的解决方案:

简而言之,你可以产生一个.disconnect() URLConnection的并行线程(让你的第二个线程休眠 timeout 毫秒后),从而触发{{1那会让你摆脱停滞的阅读。

答案 2 :(得分:1)

有关处理此情况的代码,请参阅http://thushw.blogspot.com/2010/10/java-urlconnection-provides-no-fail.html

已编辑:实际上,使用setSoTimeout设置套接字超时(以毫秒为单位)(如Joop Eggen的链接评论中所示)可能更好。