2010-12-03 9 views

答えて

1

Javaストリームのread(byte[])メソッドは、要求されたバイト数よりも少ないバイト数を読み取ることがあります。

インターネット上のファイル私はあなたがHTTP URLの内容を意味するものと仮定します。

HTTPレスポンスの中にはContent-Lengthがあらかじめ与えられていないものもありますが、そうしているように正しいサイズのバイト配列をあらかじめ割り当てることはできません。

Androidで利用可能なApache HTTPクライアントライブラリには、URLのコンテンツを完全に取得し、適切なサイズのバイト配列として返すヘルパーメソッドEntityUtils.toByteArray()が用意されています。メモリ内の全体の応答をリードすると常に最善の解決策ではないことを

public byte[] fetchURL(String url) throws IOException, ClientProtocolException { 
     HttpClient httpclient = new DefaultHttpClient(); 
     HttpGet httpget = new HttpGet(url); 
     HttpResponse response = httpclient.execute(httpget); 
     HttpEntity entity = response.getEntity(); 
     return EntityUtils.toByteArray(entity); 
} 

注:

は、ここでそれを使用してコードの一部です。ダウンロードの進捗状況をユーザーに報告するか、大きなドキュメントを段階的に解析することが望ましい場合があります。実際、応答はRAM(例えば、大きなビデオストリーム)に収まらないことさえある。

1

通常の読み取りコマンドは、要求された長さまでいくつかのバイト数を読み取ります。戻り値のチェックを含めることはプログラマに任されています(読み取られたバイト数を示します)。要求された長さ全体を読み込むreadFullyメソッドもありますが、それは非常に長い時間ブロックする可能性があり、大きなストリームを読み込んでいる途中で中断することはありません。

1

私のバイト配列は呼び出し後に部分的にしか埋めるべきではありません。

はい。あなたのアンドロイドアプリケーションは、readコールから戻る前に、ストリーム全体がダウンロードされるのを待つ必要はありません。

特定の使用例では、これは(明らかに)迷惑です。他のユースケースでは、それはreadがこのように振る舞う重要な要件です:

  • アプリケーションが処理して、リモート・サーバは、まだデータを送信している間に、ユーザに結果を提供を開始する必要があるかもしれません。

  • リモートサーバーは、実際には、クライアントからの何らかのアプリケーションレベルの応答を待ってからデータを送信します。 (これはHTTPやFTPを使用している場合は適用されませんが、読み込んでいるストリームはおそらくトランスポート層のソケットストリームをラッピングしています。そのレベルではプレゼンテーションレイヤプロトコルの詳細については何も知られていません)

    • readリターンがゼロになるまでループを使用して読み続ける:

    ソリューションです。

  • Apache HttpClientを使用している場合は、応答の内容全体を取得する方法があります。
  • Apache Commonsには、ストリームまたはリーダー全体を読み取るヘルパーメソッドを持つIOUtilsクラスが含まれています。

ところで、この動作は、read(byte[], ...)メソッドのjavadocsで明示的に指定されています。

関連する問題