如何终止 BufferedInputStream .read() 调用

发布于 2024-12-29 17:09:11 字数 368 浏览 0 评论 0原文

我正在编写一个程序来从服务器下载非常大的文件(~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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾`听者〃 2025-01-05 17:09:11

我发现的唯一可靠的方法是将 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 示例,但我知道您可以自定义套接字初始化。

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.

青朷 2025-01-05 17:09:11

请参阅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.

弥繁 2025-01-05 17:09:11

您的 URLConnection 上是否有 .setReadTimeout(int timeout)

-- 编辑

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

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

Have you .setReadTimeout(int timeout) on your URLConnection?

-- EDIT

See answer from @DNA for a neat solution:

in short words you can spawn a parallel thread that .disconnect()s the URLConnection (after letting your second thread sleep for timeout milliseconds), thus triggering an IOException that'll get you out of the stalled read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文