Java开发:文件上传和下载

一、文件上传

使用MultipartFile 类型接收参数;

调用上传有两种方式:

方式一:使用curl命令

curl -F "file=@/data/filename.txt" http://localhost:8080/upload --verbose

方式二:使用html,写一个form表单:

同样是POST请求,为何文件上传的功能会慢?其中一个原因是, 使用multipart/form-data编码,需要对数据进行分块处理,增加时间开销。服务器端也需要解析这些分块数据,并将其转化为文件或其它形式处理,这个过程也会增加时间开销。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Upload</title>
</head>
<body>
<div style="margin-left: 300px; margin-top: 50px;"><form action="/upload" method="post" enctype="multipart/form-data" accept-charset="UTF-8"><input type="file" name="file"/><br/><br/><button type="submit">上传</button></form>
</div>
</body>
</html>

Java后端上传示例:

    @RequestMapping(value = "/upload", method = RequestMethod.POST)public String upload(@RequestParam("file") MultipartFile file) {try {//String dirPath = uploadPath + File.separator + port;这里要在本地留存一份文件,可以参考hutool的FileUtil临时文件(temp)做改进String dirPath = "D:\\桌面\\bx";File dirFile = new File(dirPath);if (!dirFile.exists()) {boolean ok = dirFile.mkdirs();log.debug("===> {} create dir {}", ok, dirPath);}String fileName = file.getOriginalFilename();String filePath = dirPath + File.separator + fileName;File dest = new File(filePath);file.transferTo(dest);log.debug("===> success upload file: {}", filePath);return dest.getName();} catch (Exception e) {throw new RuntimeException(e);}}

测试:
在这里插入图片描述
此时还会在D:\桌面\bx留存一份文件

一、文件下载

后端两种写下载的方式:返回void和返回byte[]

(1)返回byte[]:需要在内存中存储整个文件内容,对于大文件可能会导致内存问题。

代码示例:

    @RequestMapping(value = "/downloadBytes")@ResponseBodypublic byte[] downloadBytes(@RequestParam("fileName") String fileName, HttpServletResponse response) {String dirPath = uploadPath + File.separator + port;String filePath = dirPath + File.separator + fileName;File file = new File(filePath);if (!file.exists() && file.isFile()) {response.setStatus(HttpServletResponse.SC_NOT_FOUND);return null;}checkState(file.exists() && file.isFile(), "file not exists: %s", filePath);// 需要添加一些头信息,响应才知道是下载的文件// 添加字符集response.setCharacterEncoding("UTF-8");// 文件类型: 方式一:指定具体的文件类型;方式二:指定其是一个二进制格式// 其它的文件类型:text/plain、application/pdf、application/vnd.ms-excel、image/jpeg、image/pngresponse.setContentType("application/octet-stream");// 文件的名称,解决中文乱码String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);// attachment (附件) 提示浏览器下载, inline 提示浏览器显示内容(如果支持的话)response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");try (InputStream inputStream = new FileInputStream(file)) {byte[] bytes = new byte[(int) file.length()];int readLen = inputStream.read(bytes);log.debug("====> readLen {}", readLen);return bytes;} catch (Exception e) {log.error(e.getMessage());response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);return null;}}

(2)返回 void 的方式通常会使用流式传输(streaming)的方式来发送文件内容,这意味着文件是以一段一段的方式发送的。这样做有几个好处:

1、节省内存:整个文件不需要一次性加载到内存中,减少了内存占用。对于大文件尤其重要。
2、更高效:可以立即开始传输文件的部分内容,而不需要等待整个文件加载完成。
代码示例:

    /*** 下载** @param fileName* @param response*/@RequestMapping(value = "/download")public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) {//dirPath 为从哪里下载,这里写的是String dirPath = "D:\\桌面\\bx"; 意思是从dirPath 下载文件名为fileName的文件String dirPath = uploadPath + File.separator + port;String filePath = dirPath + File.separator + fileName;File file = new File(filePath);if (!(file.exists() && file.isFile())) {response.setStatus(HttpServletResponse.SC_NOT_FOUND);log.debug("====> file not exists: {}", filePath);return;}// 需要添加一些头信息,响应才知道是下载的文件// 添加字符集response.setCharacterEncoding("UTF-8");// 文件类型: 方式一:指定具体的文件类型;方式二:指定其是一个二进制格式// 其它的文件类型:text/plain、application/pdf、application/vnd.ms-excel、image/jpeg、image/pngresponse.setContentType("application/octet-stream");// 文件的名称,解决中文乱码String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);// attachment (附件) 提示浏览器下载, inline 提示浏览器显示内容(如果支持的话)response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");// 文件的长度response.setContentLength((int) file.length());try (InputStream inputStream = new FileInputStream(file);BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {byte[] bytes = new byte[1024 * 16];int len = 0;ServletOutputStream outputStream = response.getOutputStream();while ((len = bufferedInputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, len);}outputStream.flush();} catch (Exception e) {log.error(e.getMessage());response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);}}

postman测试结果:
在这里插入图片描述
点这里就可以保存到文件夹;
参考:https://blog.csdn.net/hefrankeleyn/article/details/140909190

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1544670.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql基本理解

系列文章目录 Mysql的基础理论知识 目录 系列文章目录 文章目录 一、数据库概述 1.数据库概念 2.数据库的作用 3.什么是关系型数据库&#xff1f; 4.Mysql的优点 5.数据库术语 6.SQL语言分类 二、Mysql安装 三、 Mysql使用 1.登录数据库、退出登录 2.创建、列出数据库 3.选择…

Node.JS有什么用?给谁用?怎么学?通俗易懂,超级详细!

现在&#xff0c;nodejs主要是前端的小伙伴来用的。前端小伙伴也不用说去怎么学node&#xff0c;而是把node当做是一个环境。我们利用这个环境去搭建上层的一些应用&#xff0c;去使用一些工具。就像学习Windows一样&#xff0c;我们没有必要深入了解Windows的每一个细节&#…

【hot100-java】【环形链表 II】

印象题 /*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {public ListNode detectCycle(ListNode head) {ListNode fasthea…

建筑工程系列专业职称评审条件大全

我们都知道&#xff0c;职称是分很多系列&#xff0c;今天甘建二主要是从建筑工程系列讲起来&#xff0c;从技术员到初级职称再到中级职称然后到高级职称&#xff0c;各个等级的评审条件给您一一解析&#xff0c;赶紧收藏起来。 ✨技术员1️⃣理工类或建筑工程相关专业大学专科…

视频生成技术分享

文本到视频&#xff08;T2V&#xff09;生成是一种技术&#xff0c;它通过将文本描述转换为视频内容&#xff0c;允许用户根据自然语言生成动态视觉媒体。近年来&#xff0c;扩散模型在这一领域取得了显著进展&#xff0c;但现有模型在处理多个对象和复杂场景时&#xff0c;面临…

android 跑了一个网易云信v1.0的app, 编译的过程中报错Entry name ‘assets/sm2/r.jks‘ collided的处理

1、一开始并没有报这个错误&#xff0c;然后直接就不知道注了什么信息以后&#xff0c;就报错&#xff0c;是因为下面的warning&#xff1a; 2、然后编译的时候就直接报下面的错误&#xff1a; 3、然后我们再之前的注解放开&#xff1a; 这样一切就正常了。 4、那么这个究竟是…

【动态规划】(五)动态规划——子序列问题

动态规划——子序列问题 子序列问题☆ 最长递增子序列&#xff08;离散&#xff09;最长连续递增序列&#xff08;连续&#xff09;最大子序和&#xff08;连续&#xff09;最长重复子数组&#xff08;连续&#xff09;☆ 最长公共子序列&#xff08;离散-编辑距离过渡&#xf…

【动态规划】(四)动态规划——打家劫舍与买卖股票

打家劫舍与买卖股票 打家劫舍问题打家劫舍打家劫舍II打家劫舍III 买卖股票问题买卖股票的最佳时机买卖股票的最佳时机II买卖股票的最佳时机III买卖股票的最佳时机IV最佳买卖股票时机含冷冻期买卖股票的最佳时机含手续费 股票问题总结 打家劫舍问题 给定一个数组&#xff0c;相…

day-59 两两交换链表中的节点

思路 只需将链表两两交换节点即可&#xff0c;如果是奇数个节点&#xff0c;最后一个节点则不用交换 解题过程 可以先自定义一个头结点thead&#xff0c;这样更便于思考交换&#xff0c;最后返回thead.next即可 Code /*** Definition for singly-linked list.* public class…

SAM+无监督学习!能发顶会的高端局组合!idea效果绝佳

学过SAM的朋友都知道&#xff0c;SAM需要对训练数据进行全面的手动标记&#xff0c;每张图像都要超过20分钟...效率有待提升。那么如何解决这个短板&#xff1f;我们考虑SAM无监督学习。 这是因为无监督学习具有无需人工标注数据的特点&#xff0c;通过将两者结合&#xff0c;…

【LeetCode】动态规划—删除并获得点数(附完整Python/C++代码)

动态规划—#740. 删除并获得点数 前言题目描述基本思路1. 问题定义:2. 理解问题和递推关系:3. 解决方法:4. 进一步优化:5. 小总结: 代码实现Python3代码实现Python 代码解释C代码实现C 代码解释 总结: 前言 给你一个整数数组 n u m s nums nums &#xff0c;你可以对它进行一…

DownShift: Tuning Shift Reduction With Reliability for Racetrack Memories

目录 DownShift: Tuning Shift Reduction With Reliability for Racetrack Memories文章摘要&#xff1a;文章的主要贡献包括&#xff1a;文章的结构如下&#xff1a;DownShiftDownShift通过以下方式改进了现有的数据放置策略&#xff1a; GROGU&#xff08;Generating Reliabi…

2024最受欢迎的3款|数据库管理和开发|工具

1.SQLynx&#xff08;原SQL Studio&#xff09; 概述&#xff1a; SQLynx是一个原生基于Web的SQL编辑器&#xff0c;由北京麦聪软件有限公司开发。它最初被称为SQL Studio&#xff0c;后改名为SQLynx&#xff0c;支持企业的桌面和Web数据库管理。SQLynx支持所有流行的数据库&a…

工业一体机实现接口与模块选配

在现代工业自动化和智能制造的浪潮中&#xff0c;工业一体机因其集成化、稳定性高和适应性强的特性而逐渐成为企业生产过程中不可或缺的设备。为了满足不同客户的需求&#xff0c;工业一体机的接口与模块选配功能显得尤为重要。 一、工业一体机的基本概念 工业一体机是将计算、…

跟着B战学习JAVA面试八股文

学习链接&#xff1a;https://www.bilibili.com/video/BV1gm411S7EX/?spm_id_from333.337.search-card.all.click&vd_sourceefbaa07876b231ae3225ba8999116807 创建线程的几种方式&#xff1f; 继承Thread类实现Runnable接口实现Callable接口通过线程池来创建线程 为什么…

【官方Mamba库】原理简述和代码解析

目录 1 代码原理简述1.1 原始结构——SSM1.2 结构改进——S4&#xff08;Structured State Space for Sequences&#xff09;1.2.1 离散化1.2.2HiPPO 1.3 最终版本——Mamba&#xff08;又称S6或selective SSMs&#xff09; 2 代码库目录结构2.1 mamba_simple.py主体结构2.1.1 …

OLED(2)驱动篇

文章目录 1 概述2 代码简述2.1 OLED 对象2.2 OLEDProtocol 对象2.3 OLEDFont 对象 3 成果展示 1 概述 1&#xff09;代码仓库&#xff1a;这里尝试了两种面向对象的方式&#xff0c;不足之处敬请指正。 OOP 方式&#xff1a;https://gitee.com/luyaocf/demo-jlc_stm32f407_oop.…

Unity 设计模式 之 行为型模式-【命令模式】【责任链模式】

Unity 设计模式 之 行为型模式-【命令模式】【责任链模式】 目录 Unity 设计模式 之 行为型模式-【命令模式】【责任链模式】 一、简单介绍 二、命令模式&#xff08;Command Pattern&#xff09; 1、什么时候使用命令模式 2、使用命令模式的好处 3、使用时的注意事项 三…

FME学习笔记

读取数据 方法一&#xff1a;add reader 通过读模块来进行数据的读取 方法二&#xff1a;FeatureReader Parameters 通过转换器来进行数据的读取 可以通过空间范围进行筛选 在FME中&#xff0c;所有数据处理都要用到的&#xff0c;绝对的重点&#xff1a;转换器&#xff…

【Python】PyCharm: 强大的 Python 开发环境

⭕️宇宙起点 &#x1f4e2; 引言&#x1f3ac; 什么是 PyCharm&#xff1f;&#x1f528; PyCharm 的核心特性1. 智能代码编辑2. 调试和测试3. 项目和代码结构导航4. 集成 AI 助手5. 远程开发6. 集成数据库7. 科学工具8. 版本控制集成9. Web 开发 &#x1f4e6; 安装 PyCharm&…