SpringMVC下载大文件时内存溢出的处理方法

SpringMVC 文件下载的两种方式 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。现如今又要写一个关于下午的业务,因此再次编写测试用例,总结了两种下载方式。基于Spring的ResponseEntity/*** SpringMVC方式*/System.out.println("操作系统Windows");}else{System.out.println("操作系统Linux"); 阅读详情

利用SpringMVC下载大文件时内存溢出的处理

文件的上传和下载是Web系统中的一个很普通的功能,实现的方式也有很多种,如利用 java.io 下面的各种IO类自己实现,或者利用 Commons IO 1 包中的 FileUtils 、 IOUtils 类中封装好的方法直接调用。由于目前我所开发的系统采用了 SpringMVC 1 来作为项目的MVC实现,所以很自然的采用 SpringMVC 1 内置的API进行文件的下载,但在实际使用过程中发现其对大文件的下载支持不太好,现把解决方案记录如下:

@RequestMapping("downloadRequireDocument")
public ResponseEntity<byte[]> downloadRequireDocument(String fileId,String fileName,String fileType,
     HttpServletRequest request) throws IOException{
	String filePath=fileName+fileId+"."+fileType;
    
	HttpHeaders headers=new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
	headers.setContentDispositionFormData("attachment",URLEncoder.encode(fileName,"UTF-8")+"."+fileType);
    
	File downloadFile=new File(request.getSession().getServletContext().getRealPath(File.separator)+filePath);
    
	return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(downloadFile),headers,HttpStatus.CREATED);
}

该段代码在下载小文件时可以正常工作,但是当要下载的文件很大时(如几百M或上G),就会发生如下错误:

java.lang.OutOfMemoryError: Java heap space
at org.apache.commons.io.output.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:271)
at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:219)
at org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:1136)

去网上搜索 java.lang.OutOfMemoryError: Java heap space 这个错误时,一般都建议我们在tomcat中添加如下类似设置来提高JVM的配置:
set JAVA_OPTS=%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize=256m -XX:MaxPermSize=256m

但即使按照把上面的参数配置都扩大一倍,在下载更大的文件时还是会遇到 java.lang.OutOfMemoryError: Java heap space 这个错误,上面的解决方法治标不治本。分析下异常堆栈可以发现问题产生的根源在于 at org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:1136) 这行代码, FileUtils.readFileToByteArray 会把文件一次性读入内存中,要下载的文件越大,需要占用的内存也越大,当文件的大小超过JVM和Tomcat的内存配置时, OutOfMemoryError 这个问题就会不可避免的发生。

弄清产生该问题的原因之后,解决的方法也很简单: 不利用Commons IO 把文件一次性读入内存,而是利用普通的文件输出流按字节分段写入文件,把占用的内存固定在一个指定的范围内,从根本上避免内存占用过高的问题 ,替代的代码如下:

@RequestMapping("downloadRequireDocument")
public void downloadRequireDocument(String fileId,String fileName,String fileType,
	HttpServletRequest request,HttpServletResponse response) throws IOException {
	
	String filePath = request.getSession().getServletContext().getRealPath(File.separator)+fileName+"."+fileType;
	fileName = URLEncoder.encode(fileName.trim(),"UTF-8")+"."+fileType;
	response.setHeader("Content-Disposition","attachment;filename="+fileName);
	InputStream is = new FileInputStream(filePath);
	
	int read =0;
	byte[] bytes = new byte[2048];
	OutputStream os = response.getOutputStream();
	while((read = is.read(bytes))!=-1){//按字节逐个写入,避免内存占用过高
		os.write(bytes, 0, read);
	}
	os.flush();
	os.close();
	is.close();
}

 

SpringMVC实战:如何用StreamingResponseBody优化大文件下载性能(附完整代码) 本文深入解析SpringMVC中StreamingResponseBody的流式文件下载优化方案,解决大文件下载时的内存溢出问题。通过源码分析、实战代码示例和性能对比,展示如何实现高效、低内存占用的文件传输,适用于金融报表、日志文件等场景。 阅读详情

相关推荐

基于Netty与SpringMVC整合的高性能文件下载系统实现

我们并没有推翻什么,也没有另起炉灶。相反,我们做了一件更有价值的事:把 SpringMVC 的大脑,装进了 Netty 的身体里。从此以后:- 你依然可以使用@Service@Autowired;- 你的业务逻辑不需要重写;- 但底层的每一次文件传输,都变得更快、更省、更稳。这不是未来科技,这是今天就能落地的工程实践。想象一下,当你轻轻一点发布按钮,系统轻松扛住数千并发下载请求,内存纹丝不动,日志干净清爽……那种掌控感,是不是特别爽?😎。

weixin_34725745的博客 663

关于Java类加载的回忆

源于蚂蚁课堂的学习,点击这里查看(老余很给力) Java底层是由C++去编写的,而C/C++由是封装汇编指令,进而转为二进制被计算机识别。所以当我们作为Java开发者,写好Java代码后,是需要进过JavaComplier进行编译生成class字节码文件,然后由类加载器将字节码文件加载至Java虚拟机内存中进行使用,JVM通过调用C的指令转汇编,从而使得代码生效。 本文将简单聊聊博主对Java类加载机制相关知识的理解。 一、Class字节码生成原理 这对于大多数开发者而已,应该耳熟能详,...

帝都的雁的博客 420

C++代码转java工具

C++代码转java工具 C++代码转java工具 C++代码转java工具

Swig/CPP2Java

实际工程可能存在如下部分:业务接口需要编程高效的语言(如Python、Java等),易于部署维护;而核心算法部分,某些场景需要高效计算,会使用性能高效的语言(如C/C++等)。对于上述场景,“粘合剂”工具可以将语言打包,实现跨语言调用。例如Java/Python可以使用Swig转换后的C/C++代码,Python可以使用JPype等调用Java代码。这种跨语言调用的场景能帮助我们解决例如不同语言间性能差异、存量代码等问题。

... 2006

C++转Java工具

C++转Java工具,对于研究jni开发很有帮助

CPlus_to_Java_Converter;C++转java工具

CPlus_to_Java_Converter(C++转java);C++转java软件

springmvc下载文件以及下载大文件方法

后台springmvc方法:  @RequestMapping(value = "/down", method = RequestMethod.GET)  public ResponseEntity download(String type,HttpSession session) throws IOException { String filename=""; switch(type)

lzy295481710的专栏 1万+

nvidia-container-toolkit 国内镜像源安装

nvidia-container-toolkit 国内镜像源安装

湫然的博客 1万+

上传大文件报内存溢出错误OutOfMemory

最近一个项目要做大的视频文件的上传和下载。本来以前的项目框架里已经有现成的代码了,是用的springMVC文件上传下载的框架,但是以前都传的小文件,没什么问题,这次需要上传大文件,就老是报错了。 搜索原因的时候,发现好像这套框架是网络里面流传得比较广的,也算是bug吧,所以贴出来了。 可惜,看不到上传文件的源码,(因为源码在领导那里,他老人家太忙)。反正最后就是各种折腾,然后找到原因了的。 原因:...

ZHANGWEI19930118的博客 1570

MySQL下载和安装教程

1.下载MySQL数据库可以访问官方网站:https://www.mysql.com/ 2.点击DOWNLOADS模块下的Community模块下的MySQL Community Server进行下载。 由于目前最新版本是:MySQL Community Server 5.7.21 建议博友下载历史版本,本博下载的是5.6.39 下载步骤: 进入,选择MySQL的版本及主机 根据自己的电脑选择相应的位数进行下载,本机是64位,点击download。 进入下.

残雪的剑的博客 4万+

CTF命令执行绕过实战:从空格过滤到无回显外带的7种核心姿势

命令执行漏洞是Web安全中的常见高危漏洞,其核心原理在于应用程序未对用户输入进行充分过滤,导致攻击者能够注入并执行系统命令。在真实环境中,安全防护措施(如WAF、输入过滤函数)普遍存在,因此漏洞利用的关键技术在于“绕过”这些过滤机制。理解过滤器的运作逻辑(如黑名单、白名单、转义、长度限制)是成功绕过的前提。通过系统学习**空格绕过**、**命令黑名单绕过**、**编码混淆**等基础技巧,并结合**无回显外带**、**反弹Shell**等高级利用链,安全研究人员能够有效应对复杂防护场景。本文以CTFshow

weixin_29315091的博客 368

java 上传2g大文件_关于springmvc下载大的文件(2G)爆出 溢出 请求帮助

问题描述客户提出部分地方的资料上传需达到2G的效果,好不容易把内存调大了 结果下载的爆出一下问题 百度了一番说是一次性读取不了多的数据,只能是片面的取出来。org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemory...

weixin_42501956的博客 577

手把手教你用TUSB2E22中继器实现eUSB2与USB 2.0互转(附实测数据对比)

本文详细介绍了如何利用TUSB2E22中继器实现eUSB2与USB 2.0的高效互转,包括技术背景、硬件设计要点、信号完整性测试方法及故障排查策略。通过实测数据对比,展示了TUSB2E22在信号延迟、功耗和眼图性能上的显著优势,为工程师提供了实用的工程方案。

weixin_29199873的博客 281

SpringMVC(三)响应处理

创建 POJO 实例并填充属性,Spring 自动转换属性名为 JSON 字段(如。快速构建 RESTful API,返回结构化数据(如查询用户信息)。类注解,自动将方法返回值序列化为 JSON(无需。将文件流包装为响应体,避免直接加载文件到内存。声明文件大小(非必须,但利于浏览器进度显示)。会将文件全部读入内存,大文件易导致 OOM。封装响应实体,精确控制状态码、头部和正文。)会被处理为 JSON 数组。无需手动处理响应头或内容协商。流式返回,无需预读字节。触发浏览器下载行为。,可能导致流关闭异常。

小安同学的博客 816

从零到英雄:Spring Boot 微服务架构全攻略

在数字化转型的时代,微服务架构已成为构建可扩展、高可用系统的首选方案。本文以“从零到英雄”为主题,详细指导读者使用Spring Boot快速构建微服务帝国。从基础环境搭建入手,逐步深入到服务发现、配置管理、负载均衡、断路器、API网关、安全认证、监控与部署等核心模块。通过大量代码示例和详细解释,包括中文注释,帮助初学者和中级开发者掌握Spring Boot的核心概念和技术实践。文章强调实际操作,涵盖RESTful API开发、数据库集成、容器化部署等内容,并讨论常见问题与优化策略。无论你是Java开发者还是

一个被知识诅咒的人 2695

CUDA-GDB(11)——调试示例演练

本博客包含三个CUDA-GDB的演练示例: ​​​​▶ Example: bitreverse ▶ Example: autostep ▶ Example: MPI CUDA Application

AI-安全-功耗 1512

Springmvc 下载文件

前言 有时候项目里需要下载文件的功能,但是一时之间不知道从何下手,故此记录。 一、使用HttpServletResponse 最简单方便的便是使用HttpServletResponse,设置一下请求头,获取到输出流。 public static void download(HttpServletRequest request, HttpServletResponse response)...

小哥哥的博客 599

Android AMS——AMS初始化(二)

Android AMS 也是一个系统服务,属于系统服务中的引导服务,在 startBootstrapServices() 方法中启动。这里我们就来看一下 ActivityManagerService 的启动流程。

小旭的专栏 773

SpringMVC怎么实现web端上传超大文件

点击选择文件

Mr_Zang666的博客 212

毕设帮扶:从0到1搭建基于YOLOv5的打架斗殴检测系统——助你搞定深度学习毕设

做完这个毕设,你已经掌握了从数据准备到模型部署、界面开发的全流程。把模型部署到边缘设备(如安防摄像头的嵌入式系统)上,实现本地化实时检测与报警;加入行为严重程度分析(如轻微推搡 vs 严重斗殴)、涉事人员数量统计,让系统从“检测”升级为“智能安防决策”;尝试融合声音、红外等多模态数据,打造全方位的暴力事件监测系统。按照这个教程一步步做,你的毕设肯定能做得很扎实。要是过程中遇到啥问题,别担心,慢慢梳理或者咱们一起聊聊,一定能把这个毕设做成你满意的作品。

LXY_LOVE36的博客 118

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SpringMVC文件下载终极指南

在Spring MVC中,ResponseEntity<T>是实现文件下载的高效灵活方案。

m0_75107803的博客 446

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SpringBoot实现大文件分片上传的方法

需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验; 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。 支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同。 支持断点续传,关闭浏览器或刷新浏览器后仍然能够

yjjatqihc的博客 632

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java实现HTTP的上传与下载

相信很多人对于java文件下载的过程都存在一些疑惑,比如下载上传文件会不会占用vm内存,上传/下载大文件会不会导致oom。下面从字节流的角度看下载/上传的实现,可以更加深入理解文件的上传和下载功能。

qq_37436172的博客 2453

js上传超大文件解决方案

需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验; 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。 支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。 支持文件夹批量上传下载,...

weixin_45525177的博客 2135

vue之大文件分段上传、断点续传

需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验; 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。 支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。 支持文件夹批量上传下载,...

weixin_45525177的博客 1466
上一篇: 使用js修改url地址参数并修改url地址
下一篇: HttpClient4.3.X 禁止自动重定向
shadow_zed
博客等级 码龄10年 6289粉丝 68原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值