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

Java HttpServer大文件传输异常求助:客户端无法下载1GB文件

大文件下载失败的解决方案

问题根源

你的代码通过Files.readAllBytes()把1GB的文件一次性加载到内存中,这会触发两个核心问题:

  1. 内存占用急剧飙升,轻则引发GC频繁卡顿,重则直接抛出OutOfMemoryError;
  2. 浏览器需要等待服务器完全加载文件后才开始接收数据,等待时间过长会导致连接超时中断。

修复代码

修改APIHandler的handle方法,改用流式分块传输,避免一次性加载整个文件到内存:

package org.org.APIServer.api;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;

public class APIServer {
    public static void startAPIServer() {
        try {
            HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
            server.createContext("/api", new APIHandler());
            server.setExecutor(null);
            server.start();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    static class APIHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            Path filePath = Path.of("pack.zip");
            
            // 设置响应头,明确这是可下载的二进制文件
            t.getResponseHeaders().set("Content-Type", "application/octet-stream");
            t.getResponseHeaders().set("Content-Disposition", "attachment; filename=\"pack.zip\"");
            
            // 告知客户端文件总大小
            long fileSize = Files.size(filePath);
            t.sendResponseHeaders(200, fileSize);
            
            // 分块读写文件,每次仅加载8KB数据到内存
            try (InputStream in = Files.newInputStream(filePath);
                 OutputStream out = t.getResponseBody()) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                    out.flush(); // 确保数据及时发送给客户端,避免连接超时
                }
            }
            // try-with-resources会自动关闭流,无需手动调用close
        }
    }
}

关键优化点说明

  • 流式传输:用8KB缓冲区分块读取文件,内存占用始终保持在极低水平;
  • Content-Disposition头:告诉浏览器将响应作为附件下载,避免浏览器尝试解析二进制内容;
  • 自动资源管理:try-with-resources语法确保流资源正确关闭,避免泄漏;
  • 即时刷新输出流:每次写入后立即flush,让客户端及时接收数据,防止连接因长时间无响应中断。

可选进阶优化

如果需要支持断点续传(用户中途中断后可恢复下载),可以处理HTTP的Range请求头,返回对应区间的文件内容,但上述修改已经能解决当前1GB文件无法下载的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:12:41