2008-11-04 42 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; 
     } 
    }