3

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

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

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

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

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

4

3 回答 3

2

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

虽然,它看起来URLConnection不允许您连接自定义 Socket 工厂。

也许您应该从 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 示例,但我知道您可以自定义套接字初始化。

于 2012-01-28T00:12:45.207 回答
1

你有你.setReadTimeout(int timeout)URLConnection吗?

- 编辑

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

简而言之,您可以生成一个并行线程(在让您的第二个线程休眠.disconnect()超时毫秒之后),从而触发一个可以让您摆脱停滞读取的线程。URLConnectionIOException

于 2012-01-27T23:42:24.050 回答
1

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

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

于 2012-01-27T23:43:35.393 回答