Reputation: 6680
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
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
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
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
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
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
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
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