3

サーバーから非常に大きなファイル(〜2GB)をダウンロードするプログラムの作成に取り組んでいます。部分的に終了したダウンロードを再開できるようにプログラムを作成しましたが、

悪いインターネット接続をシミュレートするために、ダウンロードの途中でイーサネットコードをルーターから引き出しています。残念ながら、これにより私のプログラムは次の呼び出しでハングします。 while((bytesRead = in.read(data)) > 0)

(ここで、bytesReadはint、inはHttpURLConnectionから構築されたBufferedInputStream、dataはバイト配列です)。

別のスレッドでin.close()を呼び出して呼び出しを「中断」しようとしましたが、インターネット接続が復元されるまで(例外がスローされるまで)効果がありません。

切断されたインターネット接続がプログラムをフリーズするのを防ぐ方法はありますか?

4

3 に答える 3

2

私が見つけた唯一の信頼できる方法は、としてインスタンス化SocketInterruptibleChannel、スタックした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のサンプルはありませんが、ソケットの初期化をカスタマイズできることは知っています。

于 2012-01-28T00:12:45.207 に答える
1

あなたはあなた.setReadTimeout(int timeout)にいますURLConnectionか?

- 編集

適切な解決策については、@DNA からの回答を参照してください。

要するに.disconnect()、 (2 番目のスレッドをタイムアウトミリ秒URLConnectionの間スリープさせた後)の並列スレッドを生成できるため、停止した読み取りから抜け出すことができます。IOException

于 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 に答える