我正在尝试使用以下方法获取URL内容的大小:

URLConnection conn = null;
URL url = null;
url = new URL("https://dl.dropboxusercontent.com/u/90210205/Default.html");
conn = url.openConnection();
conn.connect();
InputStream in = new BufferedInputStream(url.openStream());
int fileSize = conn.getContentLength();
System.out.println("File size " + fileSize);
while (in.read() != -1) {
    i++;
}
in.close();
System.out.println("Read " + i + " bytes of a possible " + fileSize);

我在doInBackground()AsyncTask中使用此代码,由于某种原因,conn.getContentLength();在应返回1273时返回10136

我在常规Java应用程序的Main中使用了上面的代码,并且conn.getContentLength();返回正确的10136值。

为什么它不能在AsyncTask中工作?

最佳答案

.getContentLength()的描述是它返回Content-Length header 字段的值。在通常情况下,这应与可读取的数据量相匹配。然而...

(1)如果使用分块编码来发送数据,则 header 可能不存在。在这种情况下,.getContentLength()返回-1,因此此处似乎不是这种情况。

(2)默认情况下,HttpURLConnection的实现请求服务器使用gzip压缩,并自动为getInputStream()的调用者解压缩数据。在这种情况下,将清除Content-Encoding和Content-Length响应 header 。

最后一句话似乎表明这里不是这种情况,因为您没有从.getContentLength()`获取-1,但是相对大小(1273/10136)使我感到怀疑。

一种测试是通过使用以下命令在请求 header 中设置可接受的编码来禁用Gzip编码:

urlConnection.setRequestProperty("Accept-Encoding", "identity");

另一个办法是“窥探”网络流量,以观察http报头和线索的数据量。

顺便说一句,url.openStream()url.openConnection().getInputStream()的便利。

09-25 16:06