1. 程式人生 > >下載網路檔案HttpURLConnection.getContentLength()大小為 -1

下載網路檔案HttpURLConnection.getContentLength()大小為 -1

做一個andriod系統,測試的時候是在android 2.2系統上測試的一切正常,等釋出的時候發現個小問題,就是當程式有更新時,需要重新下載APK,為了友好,做了個進度條,但是在 2.2以上的系統中進度條不會走動,部分程式碼如下:

   HttpURLConnection conn = (HttpURLConnection)url.openConnection();    conn.connect();

 int length = conn.getContentLength();

   InputStream is = conn.getInputStream();

    經過debug,發現是由於,conn.getContentLength() 時獲取到的值為 -1,導致計算進度時,結果有誤,永遠為負數。在網上查資料都說是服務端沒有設content length,跟服務端協商,加上這個就行了。但是為毛2.2,的時候就可以服務端也沒設啊,查API :Returns the content length in bytes specified by the response header field content-length or -1 if this field is not set.

看API也似乎是這個意思。本來打算投降了,跟服務端商量下,看能不能主動加上。突然手賤多點了下查詢,發現這麼一段話:

      By default this implementation of HttpURLConnection requests that servers use gzip compression. Since getContentLength() returns the number of bytes transmitted, you cannot use that method to predict how many bytes can be read from getInputStream()

. Instead, read that stream until it is exhausted: when read() returns -1. Gzip compression can be disabled by setting the acceptable encodings in the request header。

似乎是說,在預設情況下,HttpURLConnection 使用 gzip方式獲取,檔案 getContentLength() 這個方法,每次read完成後可以獲得,當前已經傳送了多少資料,而不能用這個方法獲取 需要傳送多少位元組的內容,當read() 返回 -1時,讀取完成,由於這個壓縮後的總長度我無法獲取,那麼進度條就沒法計算值了。

要取得長度則,要求http請求不要gzip壓縮,具體設定如下

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn .setRequestProperty("Accept-Encoding","identity");
conn.connect();

int length = conn.getContentLength();

InputStream is = conn.getInputStream();