javaMan
javaMan

Reputation: 6680

How to calculate a file size from URL in java

I'm attempting to get a bunch of pdf links from a web service and I want to give the user the file size of each link.

Is there a way to accomplish this task?

Thanks

Upvotes: 25

Views: 37650

Answers (7)

Michel Jung
Michel Jung

Reputation: 3276

The accepted answer is prone to NullPointerException, doesn't work for files > 2GiB and contains an unnecessary call to getInputStream(). Here's the fixed code:

public long getFileSize(URL url) {
  HttpURLConnection conn = null;
  try {
    conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("HEAD");
    return conn.getContentLengthLong();
  } catch (IOException e) {
    throw new RuntimeException(e);
  } finally {
    if (conn != null) {
      conn.disconnect();
    }
  }
}

Update: The accepted was updated but still has issues.

Upvotes: 21

android developer
android developer

Reputation: 116322

In case you are on Android, here's a solution in Java:

/**@return the file size of the given file url , or -1L if there was any kind of error while doing so*/
@WorkerThread
public static long getUrlFileLength(String url) {
    try {
        final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
        urlConnection.setRequestMethod("HEAD");
        final String lengthHeaderField = urlConnection.getHeaderField("content-length");
        Long result = lengthHeaderField == null ? null : Long.parseLong(lengthHeaderField);
        return result == null || result < 0L ? -1L : result;
    } catch (Exception ignored) {
    }
    return -1L;
}

And in Kotlin:

/**@return the file size of the given file url , or -1L if there was any kind of error while doing so*/
@WorkerThread
fun getUrlFileLength(url: String): Long {
    return try {
        val urlConnection = URL(url).openConnection() as HttpURLConnection
        urlConnection.requestMethod = "HEAD"
        urlConnection.getHeaderField("content-length")?.toLongOrNull()?.coerceAtLeast(-1L)
                ?: -1L
    } catch (ignored: Exception) {
        -1L
    }
}

If your app is from Android N, you can use this instead:

/**@return the file size of the given file url , or -1L if there was any kind of error while doing so*/
@WorkerThread
fun getUrlFileLength(url: String): Long {
    return try {
        val urlConnection = URL(url).openConnection() as HttpURLConnection
        urlConnection.requestMethod = "HEAD"
        urlConnection.contentLengthLong.coerceAtLeast(-1L)
    } catch (ignored: Exception) {
        -1L
    }
}

Upvotes: 3

user1723178
user1723178

Reputation:

Using a HEAD request, you can do something like this:

private static int getFileSize(URL url) {
    URLConnection conn = null;
    try {
        conn = url.openConnection();
        if(conn instanceof HttpURLConnection) {
            ((HttpURLConnection)conn).setRequestMethod("HEAD");
        }
        conn.getInputStream();
        return conn.getContentLength();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        if(conn instanceof HttpURLConnection) {
            ((HttpURLConnection)conn).disconnect();
        }
    }
}

Upvotes: 46

Arpan Sarkar
Arpan Sarkar

Reputation: 2406

You can try this..

private long getContentLength(HttpURLConnection conn) {
    String transferEncoding = conn.getHeaderField("Transfer-Encoding");
    if (transferEncoding == null || transferEncoding.equalsIgnoreCase("chunked")) {
        return conn.getHeaderFieldInt("Content-Length", -1);
    } else {
        return -1;
    }

Upvotes: 0

user1723813
user1723813

Reputation:

The HTTP response has a Content-Length header, so you could query the URLConnection object for this value.

Once the URL connection has been opened, you can try something like this:

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...
       ...
    }
}

Upvotes: 3

Christopher Will
Christopher Will

Reputation: 3064

Did you try already to use getContentLength on the URL connection? In case the server responses a valid header you should get the size of the document.

But be aware of the fact that the webserver might also return the file in chunks. In this case IIRC the content length method will return either the size of one chunk (<=1.4) or -1 (>1.4).

Upvotes: 4

AlexR
AlexR

Reputation: 115328

Try to use HTTP HEAD method. It returns the HTTP headers only. The header Content-Length should contain information you need.

Upvotes: 10

Related Questions