如何杀死一个BufferedInputStream .read()调用 [英] How to kill a BufferedInputStream .read() call

查看:571
本文介绍了如何杀死一个BufferedInputStream .read()调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



我试图通过在另一个线程上调用in.close()来中断该调用,但是直到互联网连接恢复为止(此时抛出异常)。



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

解决方案

可靠的方法是将 Socket 实例化为 InterruptibleChannel ,并对卡住的IO线程执行中断。 (BTW,您不必使用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);

//这里获取java.io.Socket
Socket socket = socketChannel.socket();

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

I'm working on writing a program to download very large files (~2GB) from a server. I've written the program to be able to resume partially finished downloads,

In order to simulate a bad internet connection, I've been pulling my ethernet cord out of my router while mid-download. Unfortunately, this causes my program to hang on the following call: while((bytesRead = in.read(data)) > 0)

(Where bytesRead is an int, in is a BufferedInputStream built from an HttpURLConnection, and data is a byte array).

I've tried to "interrupt" the call by calling in.close() on another thread, but it has no effect until the internet connection is restored (at which time an exception is thrown).

Is there any way I can prevent a severed internet connection from freezing my program?

解决方案

The only reliable way I found is to instantiate Socket as an InterruptibleChannel, and do an interrupt on a stuck IO thread. (BTW, you don't have to use asynchronous NIO calls with InterruptibleChannels, blocking I/O works fine, you just have a really nice and uniform way of kicking the stuck exchanges)

Though, it looks like URLConnection does not allow you to hook up a custom Socket factory.

Maybe you should investigate HttpClient from Apache.

EDIT

Here is how you create Interruptible Socket.

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( );

I don't have HttpClient sample, but I know that you can customize socket initialization.

这篇关于如何杀死一个BufferedInputStream .read()调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆