2012-05-03 86 views
6

我有一個URL,當我在瀏覽器中輸入時,可以完美地打開圖像。但是,當我嘗試下面的代碼,我得到getContentLength()爲-1: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發送響應,您將無法預先計算大小。響應流式傳輸,您只需分配一個緩衝區來存儲圖像,直到流完成。請注意,如果您可以保證圖像足夠小以適應內存,則應該只執行此操作。如果圖像可能很大,則將響應流式傳輸到閃存存儲器是一個相當合理的選擇。

在內存解決方案:

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 

從理論上講,如果HTTP客戶介紹自己作爲HTTP 1.0,大多數服務器將切換回非流模式,但我不相信這是一個可能性用於URLConnection。

+0

感謝您的回答。但我需要該數據的字節[](圖像)。如果我沒有這個大小,那麼請指導我如何獲得byte []? – Khawar