2012-10-09 41 views
12

我试图从一个web服务中获得一堆pdf链接,我想给用户每个链接的文件大小。如何从java中的URL计算文件大小

有没有办法完成这项任务?

谢谢

+0

恐怕你将不得不下载文件至少一次以得到确切的大小。 (您可能希望将来存储,但如果服务器上的文件发生更改,数据将失效) – Nishant

+1

@Nishant这是不正确的。 'HTTP HEAD'请求会返回有关您执行'HTTP GET'请求时会得到的信息的信息,该请求应包含返回请求的大小。你当然可以做'HEAD'请求并解析响应。 – Thor84no

+1

啊,好的。很高兴知道。谢谢@ Thor84no – Nishant

回答

22

使用HEAD请求,你可以做这样的事情:

private static int getFileSize(URL url) { 
    URLConnection conn = null; 
    try { 
     conn = url.openConnection(); 
     if(conn instanceof HttpURLConnection) { 
      ((HttpURLConnection)conn).setRequestMethod("HEAD"); 
     } 
     conn.getInputStream(); 
     return conn.getContentLength(); 
    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } finally { 
     if(conn instanceof HttpURLConnection) { 
      ((HttpURLConnection)conn).disconnect(); 
     } 
    } 
} 
+0

我得到了下面的异常:java.io.IOException:服务器返回的HTTP响应代码:405的URL。我可以在浏览器中打开pdf链接。这是否意味着这个URL不会允许头部请求? – javaMan

+1

你能分享你的请求URL吗? – 2012-10-09 13:28:36

+0

我很抱歉...网址需要我的凭据。我无法分享它。 :( – javaMan

6

尝试使用HTTP HEAD方法。它仅返回HTTP标头。标题Content-Length应该包含您需要的信息。

2

您是否尝试过使用URL连接上的getContentLength? 如果服务器响应一个有效的头文件,你应该得到文件的大小。

但请注意,网络服务器也可能会以大块的形式返回文件。在这种情况下,IIRC内容长度方法将返回一个块的大小(< = 1.4)或-1(> 1.4)。

3

HTTP响应有一个Content-Length头,所以你可以查询此值的URLConnection对象。

一旦URL连接已经打开,你可以尝试这样的事:

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... 
     ... 
    } 
} 
0

你可以试试这个..

private long getContentLength(HttpURLConnection conn) { 
    String transferEncoding = conn.getHeaderField("Transfer-Encoding"); 
    if (transferEncoding == null || transferEncoding.equalsIgnoreCase("chunked")) { 
     return conn.getHeaderFieldInt("Content-Length", -1); 
    } else { 
     return -1; 
    } 
3

接受的答案是容易NullPointerException,不为文件> 2GiB工作,并包含对getInputStream()的不必要的调用。这里的固定代码:

public long getFileSize(URL url) { 
    HttpURLConnection conn = null; 
    try { 
    conn = (HttpURLConnection) url.openConnection(); 
    conn.setRequestMethod("HEAD"); 
    return conn.getContentLengthLong(); 
    } catch (IOException e) { 
    return -1; 
    // Or wrap into a (custom, if desired) RuntimeException so exceptions are propagated. 
    // throw new RuntimeException(e); 
    // Alternatively you can just propagate IOException, but, urgh. 
    } finally { 
    if (conn != null) { 
     conn.disconnect(); 
    } 
    } 
}