2016-08-21 8 views
0

私は、RangeリクエストとApacheのhttpclientを使用してHTTP経由で私のサーバからムービーをダウンロードするダウンロードアプリケーションをビルドしています。リクエストを実行してレスポンスを処理するのに問題はありませんが、後でダウンロードを再開するには、サーバーへの接続を閉じる(アプリケーションを閉じるときに)接続を開いたままにしてダウンロードを続行します。Rangeリクエスト後にapacheのhttpclientを閉じる方法

全体のダウンロードは、一度に複数のダウンロードを処理するスレッドでビルドされています。 私はprivate boolean runningスレッドを永遠に実行するのをやめます。

これは私が私の要求を実行し、応答データを処理する方法である:

HttpGet req = new HttpGet(url.toString()); 

req.setHeader("If-Range", "Wed, 11 Jan 1984 08:00:00 GMT"); 
req.setHeader("Range", "bytes=" + (bytes_read+1) + "-"); 

HttpResponse res = client.execute(req); 

if (res.getStatusLine().getStatusCode() == 206) { 
    ReadableByteChannel rbc = Channels.newChannel(res.getEntity().getContent()); 
    FileChannel fc = new FileOutputStream(new File("test.mp4", false).getChannel(); 
    int n; 
    ByteBuffer buffer = ByteBuffer.allocate(16*8192); 
    while((n = rbc.read(buffer)) > 0 && running){ 
     buffer.flip(); 
     fc.write(buffer); 
     buffer.clear(); 
    } 
} 

私のコードのこの部分は、限り、私はダウンロードを中断しようとしないと正常に動作します。

しかし、私はシャットダウンするように、このようなダウンロード、

public void shutdown(){ 
    running = false; 
    rbc.close(); 
    fc.close(); 
    client.close(); 
} 

rbc.close();の停止方法のブロックの実行を試してみてください。私はコードのこの部分をデバッグしました。実行中のフラグはそのジョブを実行し、スレッドを終了させます。 しかし、コンソールを見ると、close()メソッドを呼び出すと、ReadableByteChannelが接続からコンテンツをダウンロードし始め、何もしなかったことがわかります。それは接続を閉じていないが、最後までダウンロードしていた。

私の質問は次のとおりです。閉じる前に、サーバーからコンテンツ全体をダウンロードするようにチャネルを停止するにはどうすればよいですか。

httpclientを閉じると、いくつかの例外がスローされます。

答えて

0

問題は指定した範囲要求ヘッダーだと思います。それは指定されたバイト番号から始まるすべてのバイトを送るようにサーバに頼みます。後であなたのコードでres.getEntity()。getContent()おそらくサーバーが送信するすべてのデータを読み込みます。データの特定のチャンクだけをリクエストすることをおすすめします。

req.setHeader("Range", "bytes=" + (bytes_read+1) + "-" + (bytes_read+1 + CHUNCK_SIZE)); 

あなたが好きなようにCHUNK_SIZEを定義します。次に、このメソッドを繰り返し呼び出して、利用可能であれば、より多くのバイトを読み取ることができます。

+0

CHUNK_SIZEにはどのサイズをお勧めしますか? 10MBから20MBの間の何か? 遅い接続でプログラムが終了するまで数分待たないでください –

+0

接続の速さと待つ時間によって異なります。 10MBか20MBは私にとっては妥当なようです。 – Guenther

関連する問題