我正在编写一个程序来从服务器下载非常大的文件(~2GB)。我已经编写了程序,可以恢复部分完成的下载,
为了模拟一个糟糕的互联网连接,我一直在下载中途时将我的以太网线从我的路由器中拔出。不幸的是,这导致我的程序挂起以下调用:
while((bytesRead = in.read(data)) > 0)
(其中bytesRead是int,in是从HttpURLConnection构建的BufferedInputStream,数据是字节数组)。
我试图通过在另一个线程上调用in.close()来“中断”调用,但是在恢复互联网连接之前它没有任何效果(此时会抛出异常)。
有什么方法可以防止被切断的互联网连接冻结我的程序?
答案 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的链接评论中所示)可能更好。