Java URLConnection:如何找出网络文件的大小?
我正在为学校开发一个项目,并且正在实现一个可用于从网络下载文件的工具(带有限制选项)。 问题是,我将有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
任何 HTTP 响应都应该包含 Content-Length 标头,因此您可以查询 URLConnection 对象以获取该值。
服务器可能并不总是能够返回准确的内容长度,因此该值可能不准确,但至少大多数时候您会获得一些可用的值。
更新:或者,现在我更完整地查看了 URLConnection javadoc,您可以使用 getContentLength() 方法。
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.
如前所述,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 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.使用 HEAD 请求,我让网络服务器回复正确的内容长度字段,否则该字段为空。 我不知道这是否普遍有效,但就我而言,它确实有效:
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:
您需要使用内容长度 (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.
正如@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.