java 防止文件下载_Spring,Java:流式文件下载以避免内存不足错误
我正在开发一个Spring MVC应用程序,用户可以在其中下载文件。用户可以点击触发下载机制的附件。Spring,Java:流式文件下载以避免内存不足错误
昨天,当该多个下载和两个具有约2 GB的文件,就引起一个内存不足错误(下面登录)。
为了避免这个问题,解决这个问题的一种方法似乎是在块流下载数据,并且只处理这些块在服务层,而不是整个文件。
不幸的是,我不知道如何继续前进,任何帮助都会很好。如果这个选项不能飞,关于如何解决这个问题的任何建议。
错误日志:
HTTP Status 500 - Handler processing failed; nested exception is java.lang.OutOfMemoryError: Direct buffer memory
type Exception report
message Handler processing failed; nested exception is java.lang.OutOfMemoryError: Direct buffer memory
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Direct buffer memory
org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1303)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:977)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
控制器代码:
@RequestMapping(value = "/download/attachment/{attachid}", method = RequestMethod.GET)
public void getAttachmentFromDatabase(@PathVariable("attachid") int attachid,
, HttpServletResponse response,) {
response.setContentType("application/octet-stream");
GroupAttachments groupAttachments = this.groupAttachmentsService.getAttachmenById(attachid);
response.setHeader("Content-Disposition", "attachment; filename=\"" + groupAttachments.getFileName() + "\"");
response.setContentLength(groupAttachments.getSendAttachment().length);
FileCopyUtils.copy(groupAttachments.getSendAttachment(), response.getOutputStream());
response.flushBuffer();
}
服务层:
@Override
public GroupAttachments getAttachmenById(int attachId) {
Person person = this.personService.getCurrentlyAuthenticatedUser();
GroupAttachments groupAttachments = this.groupAttachmentsDAO.getAttachmenById(attachId);
GroupMembers groupMembers = this.groupMembersService.returnMembersMatchingUsernameAccountId(person.getUsername(),
groupAttachments.getGroupId());
if (!(groupMembers == null)) {
if (person.getUsername().equals(groupMembers.getMemberUsername())) {
try {
Path path = Paths.get(msg + groupAttachments.getGroupId() + "/" +
groupAttachments.getFileIdentifier());
groupAttachments.setSendAttachment(Files.readAllBytes(path));
return groupAttachments;
} catch (IOException ignored) {
this.groupAttachmentsDAO.removeAttachment(attachId);
return null;
}
}
return null;
} else {
return null;
}
}
谢谢。 :-)
更新
新的下载机制:
控制器:
public ResponseEntity getAttachmentFromDatabase(@PathVariable("attachid") int attachid,
@PathVariable("groupaccountid") Long groupAccountId, @PathVariable("api") String api,
HttpServletResponse response,
@PathVariable("type") boolean type) {
Path path = this.groupAttachmentsService.getAttachmentPathById(attachid);
GroupAttachments groupAttachments = this.groupAttachmentsService.getAttachmentObjectOnlyById(attachid);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\""+groupAttachments.getFileName()+"\"");
try {
OutputStream outputStream = response.getOutputStream();
Files.copy(path,outputStream);
outputStream.flush();
outputStream.close();
response.flushBuffer();
}
服务层:
@Override
public Path getAttachmentPathById(int attachId){
Person person = this.personService.getCurrentlyAuthenticatedUser();
GroupAttachments groupAttachments = this.groupAttachmentsDAO.getAttachmenById(attachId);
GroupMembers groupMembers = this.groupMembersService.returnMembersMatchingUsernameAccountId(person.getUsername(),
groupAttachments.getGroupId());
if (!(groupMembers == null)) {
if (person.getUsername().equals(groupMembers.getMemberUsername())) {
try {
return Paths.get(msg + groupAttachments.getGroupId() + "/" +
groupAttachments.getFileIdentifier());
} catch (Exception ignored) {
return null;
}
}
return null;
} else {
return null;
}
}
+1
您正在阅读的一切到内存中,不这样做......的'Files.readAllBytes'加载整个'2Gb'到内存中。根本不要。延迟加载,而不是首先加载它,逐个阅读并直接流式传输。改为使用'Files.copy(Path,OutputStream)'。 –
+0
复制将流式传输,而不是加载它。请阅读评论... –
+0
@ M.Deinum:抱歉误读。我已经更新了代码,并且用Files.copy(path,outputStream)尝试过,效果很好。我已经在主帖中发布了更新的代码,请你检查是否有可能的优化。谢谢。 –
java 防止文件下载_Spring,Java:流式文件下载以避免内存不足错误相关推荐
- 对象存储 OSS 文件下载方法:流式下载和本地下载
OSS Java SDK提供了丰富的文件下载方式: 流式下载 下载到本地文件 创建对象 ossClient 实例化后,可以先进行一步非空判断,确定该对象存储中有我们要找的 bucket 和 文件.判断 ...
- Java:以CSV格式流式传输JDBC结果集
在上一篇文章中 ,我展示了如何将java.sql.ResultSet转换为JSON并将其流回调用方. 这篇文章是关于以CSV格式流式传输的. 流式传输使您可以一点一点地传输数据,而不必将所有数据都加载 ...
- php下载二进制流文件下载,从MySQL流式传输二进制文件以使用PHP下载
我有一个存储在MySQL表longblob字段中的Excel电子表格.我需要检索此数据,然后将其作为可下载文件传输给用户,最好不要先将其写入磁盘. 可能? 编辑 – 呃,刚想通了--发表在下面的答案. ...
- JStorm—实时流式计算框架入门介绍
JStorm介绍 JStorm是参考storm基于Java语言重写的实时流式计算系统框架,做了很多改进.如解决了之前的Storm nimbus节点的单点问题. JStorm类似于Hadoop ...
- 20190827 On Java8 第十四章 流式编程
第十四章 流式编程 流的一个核心好处是,它使得程序更加短小并且更易理解.当 Lambda 表达式和方法引用(method references)和流一起使用的时候会让人感觉自成一体.流使得 Java ...
- JavaSwing_1.1: FlowLayout(流式布局)
本文链接: http://blog.csdn.net/xietansheng/article/details/72814541 Java Swing 图形界面开发(目录) 1. 概述 官方JavaDo ...
- 任意java程序都可以是servlet吗_C#从Java servlet中获取文件流实现任意文件下载
目的: 从C#创建的客户端中向Java创建的servlet提交请求(不知道这是否算作严格的CS架构),servet返回一个文件流( 任意格式的文件 ),然后通过C#获取该文件流并保存到本地,使得文件可 ...
- java流式上传下载_精讲RestTemplate第6篇-文件上传下载与大文件流式下载
C++Templates(第2版英文版) 123.24元 (需用券) 去购买 > 本文是精讲RestTemplate第6篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在S ...
- 实现文件下载的java代码
实现文件下载的java代码 //这是实现下载类(servlet),详细思路代码例如以下: //也可连接数据库 package com.message; import javax.servlet.*; ...
最新文章
- 线性代数的本质与几何意义 02. 线性组合、张成的空间、基(3blue1brown 咪博士 图文注解版)...
- $‘\r‘: command not found解决方法
- iPhone XS MAX全球首碎!一看官方维修价 网友:修不起!
- linux中pthread_kill函数详解
- Python3打印当前系统时间
- Java注释--单行注释、多行注释、文档注释
- 适用于openvino 2020.2的yolov5的docker制作
- WPF 动态图片按钮
- JavaScript中数组高级编程实践
- win7开启telnet工具
- python 麦克风人声检测_物超所值的人声麦克风推荐
- IntelliJ IDEA使用教程(动图详解):Mac 系统下安装 IntelliJ IDEA
- linux怎么下载ftp文件夹,命令行 - 如何在Linux上通过FTP递归下载文件夹
- 愿你我,能被这世界温柔以待
- 路由器硬改内存笔记1-理论
- 实现mac状态栏图标的隐藏
- 输出某年某月某日的c语言程序,输入某年某月某日,输出这是今年的第几天,C语言问题...
- matlab模拟塞曼图谱,塞曼效应理论与实验分析.doc
- sql语句实现查询实例
- 关于双击此电脑、回收站、控制面板等提示找不到应用程序解决方案
热门文章
- mysql 非正常关闭,centos非正常关机后,mysql竟然启动不了
- 查看target/classes/.../dao/文件夹下,发现只有mapper的class文件,而没有xml文件 的解决方法。
- asp.net panel 加html,ASP.NET 页面中动态增加的控件、添加事件
- keyvaluepair_C# KeyValuePairTKey,TValue的用法【转】 .
- oauth最后的确认按钮_spring-oauth集成cas单点登录,登陆完成进入授权页面后,按回退按钮进入404页面的问题...
- php时间函数 1天,PHP函数第20款:两个时间相差的天数SubTime,不满1天按1天算
- sql 树状结构中知道 父节点与孙节点_集群环境中使用Zookeeper实现分布式幂等控制...
- smarty中打印php变量,smarty用php标签怎么输出变量
- python【数据结构与算法】红黑树概念辨析
- K-Means原理解析