如何终止 BufferedInputStream .read() 调用
我正在编写一个程序来从服务器下载非常大的文件(~2GB)。我编写的程序能够恢复部分完成的下载,
为了模拟糟糕的互联网连接,我在下载过程中将以太网线从路由器中拔出。不幸的是,这导致我的程序挂起以下调用: while((bytesRead = in.read(data)) > 0)
(其中 bytesRead 是一个 int,in 是一个从 HttpURLConnection 构建的 BufferedInputStream,data 是一个字节数组)。
我尝试通过在另一个线程上调用 in.close() 来“中断”调用,但直到互联网连接恢复(此时抛出异常),它才会生效。
有什么办法可以防止互联网连接中断而冻结我的程序吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我发现的唯一可靠的方法是将 Socket 实例化为 InterruptibleChannel,并在卡住的 IO 线程上执行中断。 (顺便说一句,你不必使用带有 InterruptibleChannels 的异步 NIO 调用,阻塞 I/O 工作得很好,你只是有一个非常好的和统一的方式来踢卡住的交换)
不过,它看起来像
URLConnection
不允许您连接自定义 Socket 工厂。也许您应该研究 Apache 的 HttpClient 。
编辑
这是创建可中断套接字的方法。
我没有 HttpClient 示例,但我知道您可以自定义套接字初始化。
The only reliable way I found is to instantiate
Socket
as anInterruptibleChannel
, 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.
I don't have HttpClient sample, but I know that you can customize socket initialization.
请参阅http://thushw.blogspot.com/2010/ 10/java-urlconnection-provides-no-fail.html 用于处理这种情况的代码
编辑:实际上,设置 Socket 超时(以毫秒为单位)使用
setSoTimeout
(如 Joop Eggen 的链接评论中所建议的)可能会更好。See http://thushw.blogspot.com/2010/10/java-urlconnection-provides-no-fail.html for code to handle this situation
Edited: actually, setting a Socket timeout (in milliseconds) using
setSoTimeout
(as suggested in the link comment from Joop Eggen) is probably better.您的
URLConnection
上是否有.setReadTimeout(int timeout)
?-- 编辑
请参阅@DNA的答案以获得一个简洁的解决方案:
简而言之,您可以生成一个并行线程,它是
.disconnect()
的URLConnection
(在让您的第二个线程之后)睡眠超时毫秒),从而触发IOException
,这将使您摆脱停滞的读取。Have you
.setReadTimeout(int timeout)
on yourURLConnection
?-- EDIT
See answer from @DNA for a neat solution:
in short words you can spawn a parallel thread that
.disconnect()
s theURLConnection
(after letting your second thread sleep for timeout milliseconds), thus triggering anIOException
that'll get you out of the stalled read.