(春季启动+ Java)大于1 GB的文件的下载API

时间:2019-10-14 09:34:40

标签: java spring-boot

我正在创建rest API,用于在Spring Boot和Java中下载文件。 我以这个https://o7planning.org/en/11765/spring-boot-file-download-example为例。

这里给出了三个示例,我尝试了前两个示例,我的文件大小大于1 GB:

1)ByteArrayResource: 这会导致我的服务器内存不足

2)InputStreamResource:产生java.io.EOFException

在两种情况下,只要文件增加300至400 MB,下载都会停止并且服务器将发生故障。

请建议如何制作更好的下载API,对于较大的文件,该API不会失败。

编辑:我尝试了注释中给出的所有建议,但是从所有方面来说,我都只能做到这一点,还添加了日志。

ERROR o.s.c.s.i.web.ExceptionLoggingFilter - Uncaught exception thrown
org.eclipse.jetty.io.EofException: null
    at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:286)
    at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:429)
    at org.eclipse.jetty.io.WriteFlusher.completeWrite(WriteFlusher.java:384)
    at org.eclipse.jetty.io.ChannelEndPoint$3.run(ChannelEndPoint.java:133)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:295)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:680)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:51)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
    at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:264)
    ... 11 common frames omitted

1 个答案:

答案 0 :(得分:0)

您可以尝试:

 @GetMapping(
        value = "/download",
        produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<?> download() throws Exception {
    File file = new File("/my/file/path");
    org.springframework.core.io.UrlResource resource = new org.springframework.core.io.UrlResource(file.toURI());
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .contentLength(resource.contentLength())
            .header(
                    HttpHeaders.CONTENT_DISPOSITION,
                    String.format("attachment; filename=\"%s\"", resource.getFilename()))
            .body(resource);

}