java - (Spring boot + Java) 大于 1 GB 文件的下载 API

标签 java spring-boot

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

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

1) 字节数组资源: 这会导致我的服务器内存不足

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

最佳答案

你可以尝试:

 @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);

}

关于java - (Spring boot + Java) 大于 1 GB 文件的下载 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58373954/

相关文章:

java - 更改 jConsole 中的方法调用弹出响应

java - Spring Boot 模型映射器 - StackOverflowError : null

spring-boot - Spring Boot使用SpEL比较@Value中的字符串

java - SMTP - 通过代理发送电子邮件失败 (JAVA)

java - 嵌入式 Cassandra : Cannot run unit tests

java - 使用 ElasticsearchTemplate 和聚合器获取聚合值

spring-boot - Spring Boot 安全性 - Thymeleaf sec :authorize not working

java - 为什么我们在 java 中声明嵌套的公共(public)静态类,即使它也在其他一些地方使用?

java - Maven 无法运行特定测试

java - 我想在类中为所有枚举创建通用方法