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

如何使用Apache CloseableHttpAsyncClient上传50GB+大文件?

解决CloseableHttpAsyncClient上传超大文件(50GB+)的问题

核心问题分析

  • 使用FileInputStream构造Multipart实体时,BufferedHttpEntity会将整个文件内容缓冲到内存,直接触发OOM;即使移除BufferedHttpEntity,流方式的实体无法提前计算Content-Length,会抛出“Content Length unknown”错误。
  • 直接传入File调用addBinaryBody方法,会触发HttpClient默认的超大Content-Length校验限制,抛出“Content length is too long”错误。

正确实现方案

要实现超大文件异步上传,需满足三个核心要求:流式传输不加载全文件到内存、绕过Content-Length校验限制、正确配置异步客户端适配大文件传输。

1. 构造流式Multipart实体

使用FileBody直接封装文件,底层基于文件随机访问流实现,不会将整个文件加载到内存:

File file = new File("pathname");
// 用FileBody封装文件,支持流式传输,自动关联文件元信息
FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY, file.getName());

MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.addPart("file", fileBody);
multipartEntityBuilder.addTextBody("filename", "File one");
HttpEntity multipartEntity = multipartEntityBuilder.build();

2. 配置异步客户端,关闭超大Content-Length校验

HttpClient默认会限制Content-Length不超过Integer.MAX_VALUE(约2GB),需关闭该校验以支持50GB+文件:

// 配置IO线程池
PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(
        IOReactorConfig.custom()
                .setIoThreadCount(Runtime.getRuntime().availableProcessors())
                .build()
);

// 构建异步客户端,关闭Content-Length校验
HttpAsyncClientBuilder clientBuilder = HttpAsyncClients.custom()
        .setConnectionManager(connManager)
        .disableContentCompression() // 避免压缩带来额外内存开销
        .setDefaultRequestConfig(RequestConfig.custom()
                .setExpectContinueEnabled(true) // 启用100-Continue,先确认服务器接受请求再传文件
                .build());

// 关键:关闭Content-Length合法性校验
clientBuilder.setHttpProcessor(new ImmutableHttpProcessor(
        new RequestContent(false) // 第二个参数设为false,解除超大Content-Length限制
));

CloseableHttpAsyncClient asyncClient = clientBuilder.build();
asyncClient.start();

3. 执行异步上传请求

直接使用构造好的multipartEntity,禁止使用BufferedHttpEntity:

HttpPost postRequest = new HttpPost("http://your-server-url/upload");
postRequest.setEntity(multipartEntity);

// 异步执行上传
Future<HttpResponse> future = asyncClient.execute(postRequest, new FutureCallback<HttpResponse>() {
    @Override
    public void completed(HttpResponse response) {
        System.out.println("上传完成,响应状态码:" + response.getStatusLine().getStatusCode());
        try {
            EntityUtils.consume(response.getEntity());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void failed(Exception ex) {
        ex.printStackTrace();
    }

    @Override
    public void cancelled() {
        System.out.println("上传被取消");
    }
});

// 按需等待上传完成(业务场景允许的话可异步处理)
future.get();
asyncClient.close();

关键说明

  • RequestContent(false):彻底关闭HttpClient对Content-Length的大小校验,支持超过2GB的文件传输。
  • FileBody:通过文件随机访问流实现真正的流式上传,内存占用仅为缓冲区大小,不会随文件体积增长。
  • Expect: 100-Continue:让服务器先确认请求合法性,避免大文件传输到一半被拒绝的带宽浪费。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:05:23