【问题标题】:How to get InputStream via Spring-Feign?如何通过 Spring-Feign 获取 InputStream?
【发布时间】:2019-09-22 17:15:28
【问题描述】:

我想通过 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 -&gt; Buffer -&gt; ByteArray -&gt; Buffer -&gt; File

我怎样才能以高效、快速的方式下载和保存文件?

【问题讨论】:

    标签: java spring-boot spring-cloud-feign feign zero-copy


    【解决方案1】:

    TL;博士。使用ResponseEntity&lt;InputStreamResource&gt; 和Java NIO

    根据SpringDecoder,Spring使用HttpMessageConverters解码响应

    作为 HttpMesageConverters 之一的 ResourceHttpMessageConverter 返回 InputStreamResource,其中包含从 Content-Disposition 派生的 InputStream 和文件名。

    但是,ResourceHttpMessageConverter 必须初始化supportsReadStreaming = true (default value) 如果您对此实现有进一步的兴趣,check this code

    所以,修改后的代码如下:

    @GetMapping("/api/v1/files")
    ResponseEntity<InputStreamResource> getFile(@RequestParam(value = "key") String key)
    

    JDK9

    try (OutputStream os = new FileOutputStream("filename.txt")) {
        responeEntity.getBody().getInputStream().transferTo(os);
    }
    

    JDK8 或更低

    使用番石榴ByteStreams.copy()

    Path p = Paths.get(responseEntity.getFilename())
    ReadableByteChannel rbc = Channels.newChannel(responeEntity.getBody().getInputStream())
    try(FileChannel fc = FileChannel.open(p, StandardOpenOption.WRITE)) {
        ByteStreams.copy(rbc, fc)
    }
    

    现在,Feign Internal Stream -&gt; File

    【讨论】:

      猜你喜欢
      • 2013-03-02
      • 2017-07-19
      • 2013-01-21
      • 2019-08-19
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多