Java URLConnection:如何找出网络文件的大小?

发布于 2024-07-08 21:22:11 字数 139 浏览 7 评论 0原文

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

I'm working on a project for school, and I'm implementing a tool which can be used to download files from the web ( with a throttling option ). The thing is, I'm gonna have a GUI for it, and I will be using a JProgressBar widget, which I would like to show the current progress of the download. For that I would need to know the size of the file. How do you get the size of the file prior to downloading the file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

舟遥客 2024-07-15 21:22:11

任何 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() 方法。

Any HTTP response is supposed to contain a Content-Length header, so you could query the URLConnection object for this value.

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

It might not always be possible for a server to return an accurate Content-Length, so the value could be inaccurate, but at least you would get some usable value most of the time.

update: Or, now that I look at the URLConnection javadoc more completely, you could just use the getContentLength() method.

风月客 2024-07-15 21:22:11

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

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

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

As mentioned, URLConnection's getContentLengthLong() is your best bet, but it won't always give a definite length. That's because the HTTP protocol (and others that could be represented by a URLConnection) doesn't always convey the length.

In the case of HTTP, the length of dynamic content typically isn't known in advance—when the content-length header would normally be sent. Instead, another header, transfer-encoding, specifies that a "chunked" encoding is used. With chunked encoding, the length of the entire response is unspecified, and the response is sent back in pieces, where the size of each piece is specified. In practice, the server buffers output from the servlet. Whenever the buffer fills up, another chunk is sent. Using this mechanism, HTTP could actually start streaming a response of infinite length.

If a file is larger than 2 Gb, its size can't be represented as an int, so the older method, getContentLength() will return -1 in that case.

ゞ花落谁相伴 2024-07-15 21:22:11

使用 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();
        }
    }

Using a HEAD request, i got my webserver to reply with the correct content-length field which otherwise was empty. I don't know if this works in general but in my case it does:

    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();
        }
    }
夏末的微笑 2024-07-15 21:22:11

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

You'll want to use the content length (URLConnection.getContentLength()). Unfortunately, this won't always be accurate, or may not always be provided, so it's not always safe to rely on it.

棒棒糖 2024-07-15 21:22:11
    //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; 
        }
    }
    //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; 
        }
    }
樱桃奶球 2024-07-15 21:22:11

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

关于 available() 方法 - 没有人可以向您保证它将返回正确的值,因此我建议您不要使用它。

As @erickson said, sometimes there is header "Transfer-Encoding: chunked", instead of "Content-Length: " and of course you have null value for length.

About the available() method - nobody can guarantee to you that it will return proper value, so I recommend you to not use it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文