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