2012-05-03 17 views
6

ブラウザに入力すると完全に画像を開くURLがあります。しかし、私は、次のコードをしようとしたとき、私は-1として)(getContentLengthを得る:URLConnection.getContentLength()は-1を返します

URL url = new URL(imageUrl); 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 

// determine the image size and allocate a buffer 
int fileSize = connection.getContentLength(); 

この背後にある理由ができるか私を導いてください?

+3

ストリーミングサービスの場合など、ContentLengthは常にあるとは限りません。また、サーバーが送信しないこともあります。存在するコンテンツの長さに依存することはできません。 – dmon

+0

@dmonそのデータ(画像)のbyte []が必要です。私はサイズがない場合は、どのようにバイト[]を得ることができますか教えてください? – Khawar

+2

それは悪い考えです。 Androidのメモリはかなり制約されており、巨大なバイト配列を割り当ててはいけません。代わりに、ディスクへのレスポンスをストリーミングし、そこからイメージを読み込む(必要に応じてサイズを変更する)必要があります。 – dmon

答えて

8

サーバーがChunked Transfer Encodingを使用して応答を送信している場合、サイズをあらかじめ計算することはできません。レスポンスはストリーミングされ、ストリームが完成するまでイメージを格納するバッファを割り当てるだけで済みます。イメージがメモリに収まるのに十分小さいことを保証できる場合にのみ、これを行うようにしてください。フラッシュストレージへの応答をストリーミングすることは、イメージが大きくなる可能性がある場合はかなり合理的な選択肢です。

インメモリソリューション:HTTPクライアントがHTTP 1.0としての地位を提示した場合に理論的には

private static final int READ_SIZE = 16384; 

byte[] imageBuf; 
if (-1 == contentLength) { 
    byte[] buf = new byte[READ_SIZE]; 
    int bufferLeft = buf.length; 
    int offset = 0; 
    int result = 0; 
    outer: do { 
     while (bufferLeft > 0) { 
      result = is.read(buf, offset, bufferLeft); 
      if (result < 0) { 
       // we're done 
       break outer; 
      } 
      offset += result; 
      bufferLeft -= result; 
     } 
     // resize 
     bufferLeft = READ_SIZE; 
     int newSize = buf.length + READ_SIZE; 
     byte[] newBuf = new byte[newSize]; 
     System.arraycopy(buf, 0, newBuf, 0, buf.length); 
     buf = newBuf; 
    } while (true); 
    imageBuf = new byte[offset]; 
    System.arraycopy(buf, 0, imageBuf, 0, offset); 
} else { // download using the simple method 

、ほとんどのサーバーはバック非ストリーミング・モードに切り替わりますが、私は、これは可能性があるとは思いませんURLConnectionの場合

+0

あなたの答えをありがとう。しかし、私はそのデータ(画像)のバイト[]が必要です。私はサイズがない場合は、どのようにバイト[]を得ることができますか教えてください? – Khawar

関連する問題