使用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
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
相关产品推荐
相关产品推荐

