31

我正在为学校做一个项目,我正在实现一个可用于从网络下载文件的工具(带有节流选项)。问题是,我将有一个 GUI,我将使用一个JProgressBar小部件,我想显示下载的当前进度。为此,我需要知道文件的大小。在下载文件之前如何获取文件的大小。

4

6 回答 6

39

任何 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...
       ...
    }

服务器可能并不总是可以返回准确的 Content-Length,因此该值可能不准确,但至少在大多数情况下您会得到一些可用的值。

更新:或者,现在我更完整地查看了 URLConnection javadoc,您可以只使用getContentLength()方法。

于 2008-11-04T19:16:49.077 回答
33

如前所述,URLConnectiongetContentLengthLong()是您最好的选择,但它并不总是给出明确的长度。那是因为 HTTP 协议(​​以及可以用 a 表示的其他协议URLConnection)并不总是传达长度。

在 HTTP 的情况下,动态内容的长度通常是事先不知道的——content-length通常何时发送标头。相反,另一个标头transfer-encoding指定使用“分块”编码。使用分块编码,整个响应的长度是未指定的,并且响应被分块发送回,其中指定了每个块的大小。实际上,服务器缓冲来自 servlet 的输出。每当缓冲区填满时,就会发送另一个块。使用这种机制,HTTP 实际上可以开始流式传输无限长度的响应。

如果文件大于 2 Gb,则其大小不能表示为int,因此在这种情况下,较旧的方法getContentLength()将返回 -1。

于 2008-11-04T19:36:42.767 回答
28

使用 HEAD 请求,我让我的网络服务器回复正确的内容长度字段,否则该字段为空。我不知道这是否普遍有效,但就我而言,它确实有效:

    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();
        }
    }
于 2011-10-06T10:31:12.867 回答
4

您需要使用内容长度 (URLConnection.getContentLength())。不幸的是,这并不总是准确的,或者可能并不总是提供,因此依赖它并不总是安全的。

于 2008-11-04T19:26:31.243 回答
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; 
        }
    }
于 2016-06-23T01:37:58.407 回答
0

正如@erickson 所说,有时会有标题“Transfer-Encoding:chunked”,而不是“Content-Length:”,当然长度为空值。

关于 available() 方法——没有人能保证它会返回正确的值,所以我建议你不要使用它。

于 2011-02-02T08:37:42.927 回答