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.
相关问题
- Angular RxJS mergeMap types
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
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.
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 aURLConnection
) 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.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:
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.
Any HTTP response is supposed to contain a Content-Length header, so you could query the URLConnection object for this value.
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.