2008-11-04 37 views
27

我正在爲學校開展一個項目,我正在實施一個可用於從網上下載文件的工具(帶有限制選項)。事情是,我將擁有一個圖形用戶界面,我將使用一個JProgressBar小部件,我希望顯示下載的當前進度。爲此我需要知道文件的大小。如何在下載文件之前獲取文件的大小。Java URLConnection:如何找出網頁文件的大小?

回答

36

任何HTTP響應是假定包含Content-Length標頭,因此您可以查詢URLConnection對象的該值。

//once the connection has been opened 
List values = urlConnection.getHeaderFields().get("content-Length") 
if (values != null && !values.isEmpty()) { 

    // getHeaderFields() returns a Map with key=(String) header 
    // name, value = List of String values for that header field. 
    // just use the first value here. 
    String sLength = (String) values.get(0); 

    if (sLength != null) { 
     //parse the length into an integer... 
     ... 
    } 

它可能並不總是能夠對服務器返回一個準確的內容長度,因此該值可能不準確,但至少你會得到一些可用價值的大部分時間。或者,現在我已經看到URLConnection javadoc更完全了,您可以使用getContentLength()方法。

+1

getContentLength()鏈接給找不到網頁,看到http://docs.oracle.com/javase/6/ docs/api/java/net/URLConnection.html#getContentLength() – Reg 2014-03-17 05:04:31

+0

getContentLength不會總是返回值。例如,執行一個請求時,會返回一個動態結果,其中內容的大小未知。 – coderama 2017-04-27 15:50:50

4

您需要使用內容長度(URLConnection.getContentLength())。不幸的是,這並不總是準確的,也可能並不總是提供的,所以依靠它並不總是安全的。

32

如上所述,URLConnection的getContentLength是您最好的選擇,但它並不總是給出確定的長度。這是因爲HTTP協議(以及可能由URLConnection表示的其他協議)並不總是表示長度。

在HTTP的情況下,動態內容的長度通常不會預先知道—當通常發送content-length標頭時。相反,另一個標頭transfer-coding指定使用「分塊」編碼。使用分塊編碼時,整個響應的長度是未指定的,並且響應被分段發回,其中指定每個片段的大小。實際上,服務器緩衝servlet的輸出。每當緩衝區填滿時,就會發送另一個塊。使用這種機制,HTTP實際上可以開始流式傳輸無限長度的響應。

您可能無法通過URLConnection獲取文件長度的另一個原因是文件大於2 Gb(這是正整數的限制)。

+2

+1的準確性。如果讀取URLConnection對象上的分塊響應的內容長度,J2SE 1.4將返回-1。 J2SE 1.3中不是這種情況。 – 2010-08-05 21:04:04

0

正如@erickson所說,有時候會有頭部「Transfer-Encoding:chunked」,而不是「Content-Length:」,當然你的長度爲空值。

關於available()方法 - 沒有人能保證它會返回適當的值,所以我建議你不要使用它。

28

使用HEAD請求,我讓我的web服務器回覆正確的內容長度字段,否則它是空的。我不知道,如果這個工程一般但對我來說它的作用:

private int tryGetFileSize(URL url) { 
     HttpURLConnection conn = null; 
     try { 
      conn = (HttpURLConnection) url.openConnection(); 
      conn.setRequestMethod("HEAD"); 
      conn.getInputStream(); 
      return conn.getContentLength(); 
     } catch (IOException e) { 
      return -1; 
     } finally { 
      conn.disconnect(); 
     } 
    } 
+1

非常適合我,非常感謝。 – z00l 2012-01-31 19:50:39

1
//URLConnection connection 

private int FileSize(String url) { 

// this is the method and it get the url as a parameter. 

     // this java class will allow us to get the size of the file. 

     URLConnection con; 

     // its in a try and catch incase the url given is wrong or invalid 

     try{ 

      // we open the stream 

      con = new URL(url).openConnection() 

      return con.getContentLength(); 
     }catch (Exception e){ 

      e.printStackTrace(); 

      // this is returned if the connection went invalid or failed. 

      return 0; 
     } 
    }