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

使用Spring WebClient下载大文件仅获取部分数据的问题咨询

问题根因

你代码里的核心错误是调用了awaitLast()方法:

  • Spring WebClient的bodyToFlux<DataBuffer>()会将大文件响应拆分为多个流式发射的DataBuffer数据块,每个块只包含文件的一小段内容
  • awaitLast()只会等待并获取Flux中发射的最后一个DataBuffer块,自然只能拿到文件末尾的小部分数据,无法获得完整文件内容

正确实现方案

你需要将所有流式返回的DataBuffer处理后再转InputStream,根据文件大小可选两种实现方式:

方案1:拼接所有DataBuffer(适合中等大小文件,内存可容纳完整文件的场景)

suspend fun downloadDocument(
    documentId: UUID
): InputStream =
    webClient.get()
        .uri("<some uri>")
        .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE)
        .retrieve()
        .bodyToFlux<DataBuffer>()
        // 收集所有DataBuffer块合并为一个
        .collectList()
        .awaitSingle()
        .let { DataBufferUtils.join(it) }
        .asInputStream(true)

方案2:转成流式InputStream(适合超大文件,避免内存溢出)

如果文件体积过大,全量拼接会占用过多内存,可以直接把Flux转成边读边加载的流式InputStream:

suspend fun downloadDocument(
    documentId: UUID
): InputStream =
    webClient.get()
        .uri("<some uri>")
        .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE)
        .retrieve()
        .bodyToFlux<DataBuffer>()
        // 转换为不占用全量内存的流式输入流
        .`as` { DataBufferUtils.toInputStream(it, true) }
        .awaitSingle()

注意:第二种方式返回的InputStream使用完成后需要主动关闭,避免资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:45:03