Android: URLConnection.getContentLength() giving incorrect value

1.8k views Asked by At

I'm trying to get the size of the contents of a URL using:

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);

I'm using this within the doInBackground() of an AsyncTask and for some reason conn.getContentLength(); is returning 1273 when it should be returning 10136.

I have used the above code within the Main of a regular Java application and conn.getContentLength(); returns the correct 10136 value.

Why isn't it working in an AsyncTask?

1

There are 1 answers

0
John Hascall On BEST ANSWER

The description of .getContentLength() is that it returns the value of the Content-Length header field. In ordinary circumstances, this should match the amount of data available to be read. However...

(1) The header may not be present if chunked-encoding is being used to send the data. In this case, .getContentLength() returns -1 so that appears not to be the case here.

(2) By default, the implementation of HttpURLConnection requests that servers use gzip compression and it automatically decompresses the data for callers of getInputStream(). The Content-Encoding and Content-Length response headers are cleared in this case.

The last sentence seems to indicate that this also is not the case here, because you are not getting -1 from .getContentLength()`, but the relative sizes (1273 / 10136) make me suspicious...

One test of this would be to disabled Gzip encoding by setting the acceptable encodings in the request header with:

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

Another would be to 'snoop' the network traffic to observer the http headers and amount of data for clues.

BTW, url.openStream() is a convenience for url.openConnection().getInputStream().