我正在为学校开展项目,我正在实施一个可用于从网上下载文件的工具(带有限制选项)。问题是,我将有一个GUI,我将使用JProgressBar
小部件,我想显示下载的当前进度。为此,我需要知道文件的大小。如何在下载文件之前获取文件的大小。
答案 0 :(得分:38)
任何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()方法。
答案 1 :(得分:33)
如上所述,URLConnection的getContentLengthLong()
是你最好的选择,但它并不总是给出明确的长度。那是因为HTTP协议(以及可能由URLConnection
表示的其他协议)并不总是传达长度。
在HTTP的情况下,通常不会提前知道动态内容的长度 - 通常会发送content-length
标头。相反,另一个标头transfer-encoding
指定使用“分块”编码。对于分块编码,未指定整个响应的长度,并且响应被分段发回,其中指定了每个片段的大小。实际上,服务器缓冲来自servlet的输出。每当缓冲区填满时,就会发送另一个块。使用这种机制,HTTP实际上可以开始流式传输无限长度的响应。
如果文件大于2 Gb,则其大小无法表示为int
,因此旧方法getContentLength()
在这种情况下将返回-1。
答案 2 :(得分: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();
}
}
答案 3 :(得分:4)
您需要使用内容长度(URLConnection.getContentLength())。不幸的是,这并不总是准确的,或者可能并不总是提供,所以依靠它并不总是安全的。
答案 4 :(得分: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;
}
}
答案 5 :(得分:0)
正如@erickson所说,有时标题为“Transfer-Encoding:chunked”,而不是“Content-Length:”,当然你的长度值为null。
关于available()方法 - 没有人能保证它会返回正确的值,所以我建议你不要使用它。