1. 概述

HTTP 协议提供了关于请求 Web 资源的全面信息。其头部字段之一 Content-Length 指定了资源的字节大小。我们可以通过 Java 的 URLConnection 类提取这些信息。

在下载前获取 Web 文件大小有助于估算所需网络流量。⚠️ 但需注意:服务器返回的大小值可能不准确,开发者可随意设置该字段值。

本教程将探讨如何使用 URLConnection 类的以下方法获取文件大小:

  • getContentLengthLong()
  • getHeaderField()

2. HTTP Content-Length 机制

Content-Length 头部字段直接表示响应体的字节大小。但需注意以下关键点:

基本原理
HTTP 作为传输协议,通过头部字段描述响应属性,Content-Length 即表示响应体大小

两大限制

  1. 当使用分块传输编码(Transfer-Encoding: chunked)时,无法预知文件总大小
  2. 服务器可能返回任意值(如 Spring 应用中开发者可手动设置),与实际文件大小不符

踩坑提醒:永远不要完全信任 Content-Length,它只是服务器声明的估算值

3. 文件大小获取方法对比

URLConnection 提供两种核心方法获取文件大小:

方法 返回类型 最大支持值 推荐场景
getContentLength() int 2 GiB 已废弃
getContentLengthLong() long 8 EiB ✅ 首选

⚠️ 关键区别

  • getContentLength() 无法处理超过 Integer.MAX_VALUE(2 GiB)的文件
  • Content-Length 头部缺失时,两方法均返回 -1
// 错误示例:大文件会溢出
int size = connection.getContentLength(); // 危险!

// 正确做法:支持超大文件
long size = connection.getContentLengthLong(); // 安全

4. 使用 getContentLengthLong() 获取大小

以获取示例 PDF 文件(29,789 字节)为例:

String fileUrl = "https://www.ingka.com/wp-content/uploads/2020/11/dummy.pdf";
URL url = new URL(fileUrl);
URLConnection urlConnection = url.openConnection();

long fileSize = urlConnection.getContentLengthLong();
if (fileSize != -1) {
    assertEquals(29789, fileSize);
} else {
    fail("无法确定文件大小");
}

执行流程:

  1. 创建 URL 对象指向目标文件
  2. 通过 openConnection() 建立连接
  3. 调用 getContentLengthLong() 获取大小
  4. 处理返回值(-1 表示失败)

5. 使用 getHeaderField() 替代方案

直接读取 HTTP 头部字段是更底层的实现方式:

@Test
void givenUrl_whenGetFileSizeUsingURLConnectionAndGetHeaderField_thenCorrect() throws IOException {
    URL url = new URL(fileUrl);
    URLConnection urlConnection = url.openConnection();

    String headerField = urlConnection.getHeaderField("Content-Length");
    if (headerField != null && !headerField.isEmpty()) {
        long fileSize = Long.parseLong(headerField);
        assertEquals(29789, fileSize);
    } else {
        fail("无法确定文件大小");
    }
}

关键步骤:

  1. 通过 getHeaderField("Content-Length") 获取原始字符串值
  2. 将字符串转换为 long 类型
  3. 处理空值情况(头部缺失时返回 null

简单粗暴:本质是手动解析 HTTP 头部,与 getContentLengthLong() 效果相同

6. 总结

获取 Web 文件大小的核心要点:

推荐方法

long size = new URL("https://example.com/file.zip")
    .openConnection()
    .getContentLengthLong();

注意事项

  1. 返回 -1 表示无法获取大小(头部缺失或分块传输)
  2. 服务器可能返回错误的大小值
  3. 大文件(>2 GiB)必须使用 getContentLengthLong()

完整示例代码见 GitHub 仓库


原始标题:Finding the Size of a Web File Using URLConnection in Java | Baeldung