24

我正在尝试从 Web 服务中获取一堆 pdf 链接,并且我想为用户提供每个链接的文件大小。

有没有办法完成这个任务?

谢谢

4

7 回答 7

44

使用 HEAD 请求,您可以执行以下操作:

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();
        }
    }
}
于 2012-10-09T13:09:46.903 回答
15

接受的答案很容易出现NullPointerException,不适用于大于 2GiB 的文件,并且包含对getInputStream(). 这是固定代码:

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

更新:接受的答案得到修复。

于 2016-10-31T13:16:31.780 回答
8

尝试使用 HTTP HEAD 方法。它仅返回 HTTP 标头。标题Content-Length应包含您需要的信息。

于 2012-10-09T13:02:36.310 回答
4

HTTP 响应有一个 Content-Length 标头,因此您可以在 URLConnection 对象中查询该值。

打开 URL 连接后,您可以尝试以下操作:

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...
       ...
    }
}
于 2012-10-09T13:22:37.353 回答
3

您是否已经尝试在 URL 连接上使用getContentLength ?如果服务器响应一个有效的标题,你应该得到文档的大小。

但请注意,网络服务器也可能以块的形式返回文件。在这种情况下 IIRC 内容长度方法将返回一个块的大小 (<=1.4) 或 -1 (>1.4)。

于 2012-10-09T13:05:04.247 回答
2

如果您使用的是 Android,这里有一个 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;
}

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

如果您的应用来自 Android N,您可以改用它:

/**@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
    }
}
于 2019-02-28T09:11:17.337 回答
0

你可以试试这个。。

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;
    }
于 2016-05-03T02:09:17.657 回答