You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java NIO中下载图片后校验文件长度与Content-Length匹配?

实现WebP下载后的Content-Length校验方案

原代码使用transferFrom时可能出现文件未完全下载的情况,要校验本地文件长度与响应头的Content-Length是否一致,你需要改用HttpURLConnection来发起请求(URL.openStream()无法获取响应头信息),具体实现步骤如下:

修改后的完整代码

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

static void downloadWebp(String url) {
    URL urlObj;
    try {
        urlObj = new URL(url);
    } catch (MalformedURLException e) {
        throw new RuntimeException("无效的URL格式", e);
    }

    HttpURLConnection connection = null;
    ReadableByteChannel readableByteChannel = null;
    Path savePath = Paths.get(System.getProperty("user.home"), "image", 
        Paths.get(urlObj.getPath()).getFileName().toString());

    try {
        // 打开HTTP连接并获取响应头
        connection = (HttpURLConnection) urlObj.openConnection();
        connection.setRequestMethod("GET");
        connection.connect();

        // 获取响应头中的Content-Length
        long expectedLength = connection.getContentLengthLong();
        if (expectedLength == -1) {
            throw new RuntimeException("响应头未返回Content-Length,无法校验");
        }

        // 开始下载文件
        readableByteChannel = Channels.newChannel(connection.getInputStream());
        try (FileOutputStream fileOutputStream = new FileOutputStream(savePath.toAbsolutePath().toString())) {
            fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
        }

        // 校验本地文件长度与Content-Length是否一致
        long actualLength = Files.size(savePath);
        if (actualLength != expectedLength) {
            // 可根据需求调整逻辑:删除不完整文件、重试下载等
            Files.deleteIfExists(savePath);
            throw new RuntimeException(String.format("文件下载不完整:预期%d字节,实际%d字节", expectedLength, actualLength));
        }

    } catch (IOException e) {
        // 异常时清理不完整文件
        try {
            Files.deleteIfExists(savePath);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        throw new RuntimeException("下载或校验失败", e);
    } finally {
        // 关闭资源
        if (connection != null) {
            connection.disconnect();
        }
        if (readableByteChannel != null) {
            try {
                readableByteChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

关键改动说明

  • 改用HttpURLConnection发起请求,通过getContentLengthLong()获取响应头中的文件预期长度(支持大文件场景)
  • 下载完成后调用Files.size(savePath)获取本地文件实际大小
  • 对比预期与实际长度,不一致时自动删除无效文件并抛出异常(可自行扩展为重试下载逻辑)
  • 补充了资源关闭与异常清理逻辑,避免残留无效文件

调用示例

downloadWebp("https://cdn.discordapp.com/attachments/1098794840742961242/1100590092957003877/Jeffery_cherry_blossoms_blooming_in_the_rain_by_Yoko_Ishii_wate_8a2f060e-32dc-4567-a3df-8bfdbb56adfd.webp");

内容的提问来源于stack exchange,提问作者djy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:52:58