我想用Spring-OpenFeign从服务器下载一个文件并保存到本地目录,零拷贝。
简单的下载方法如下:
import org.apache.commons.io.FileUtils
@GetMapping("/api/v1/files")
ResponseEntity<byte[]> getFile(@RequestParam(value = "key") String key) {
ResponseEntity<byte[]> resp = getFile("filename.txt")
File fs = new File("/opt/test")
FileUtils.write(file, resp.getBody())
}
字符串
在这段代码中,数据流将像这样feign Internal Stream -> Buffer -> ByteArray -> Buffer -> File
我怎样才能下载和保存一个文件内存有效和更快的方式?
2条答案
按热度按时间db2dz4w81#
TL; DR.使用
ResponseEntity<InputStreamResource>
和Java NIO根据SpringDecoder,Spring使用HttpMessageConverters解码响应
ResourceHttpMessageConverter是HttpMesageConverters之一,它返回InputStreamResource,其中包含从
Content-Disposition
派生的InputStream和文件名。但是,ResourceHttpMessageConverter必须初始化
supportsReadStreaming = true (default value)
如果您对此实现有进一步的兴趣,请检查此代码。因此,更改的代码如下:
字符串
JDK 9
型
JDK 8以下
使用Guava ByteStreams.copy()
型
现在,
Feign Internal Stream -> File
soat7uwm2#
假设你想使用Feign从外部API获取一个流。你应该在你的feign方法中使用
ByteArrayResource
作为响应类型。在你的feign接口中,让你的方法返回
ByteArrayResource
来使用一个流字符串
关于接受的答案的评论:
只有当流只被消耗一次时,你才可以用
InputStreamResource
代替ByteArrayResource
,如果你需要多次消耗流,你不应该使用InputStreamResource
。引用自
InputStreamResource
classjavadoc:只有在没有其他特定的
Resource
实现适用的情况下才应该使用。特别是,如果可能,首选ByteArrayResource
或任何基于文件的Resource
实现。与其他
Resource
实现不同,这是一个 * 已打开 * 资源的描述符-因此从isOpen()
返回true
。如果需要将资源描述符保存在某处,或者如果需要多次从流中读取,请不要使用
InputStreamResource
。