byte[]转MultipartFile、byte[]转File一次看个够

目录

需求背景

当你需要将byte[]MultipartFileFile实现互转时,无外乎以下场景:

  1. 保存第三方接口返回二进制流
  2. 前/后端文件流上传
  3. 微服务间调用
  4. 文件格式转换

正如你所需要的,通过搜索引擎筛选到我的本篇文章是因为你在开发中需要将byte[]转为MultipartFileFile格式的文件,以上需求在业务开发中是用户、客户、产品经理所喜闻乐见的,类似的文章在各大博客平台同样多如牛毛,也许你看了许多其他博主写的文章,按他们的代码按部就班去做但并没达到你需要的效果,是的,我在开发过程中也遇到了这样的痛点,因此有了这篇文章,写本文的目的意在为自己积累知识点,另外也帮助他人少走弯路。

希望我的文章能够帮您快速、高效解决您的问题,这是我莫大的荣幸。

“赠人玫瑰,手有余香” --谚语

byte[]转MultipartFile

错误示例-MockMultipartFile

首先来看一下摘自Spring官网对MockMultipartFile的一段描述:

public class MockMultipartFile extends Object implements MultipartFile

Mock implementation of the MultipartFile interface.

Useful in conjunction with a MockMultipartHttpServletRequest for testing application controllers that access multipart uploads.

虽然MockMultipartFile实现了MultipartFile接口,重点在于后一句对其作用的描述:用于测试访问分段上传, 所以这个类在正式环境是无法使用的,在我看来使用MockMultipartFile来实现byte[]MockMultipartFile的博客都是误人子弟,因为你的代码不仅仅是运行在测试类中,而都是要发布在生产环境的。

maven坐标:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-mock -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-mock</artifactId><version>2.0.8</version><scope>test</scope>
</dependency>
byte[] testFile = new byte[1024];
InputStream inputStream = new ByteArrayInputStream(testFile);
MultipartFile file = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);

CommonsMultipartFile介绍

CommonsMultipartFileSpring 框架3.1版本后引入,用于与Apache Commons FileUpload 库集成的适配器。它实现了 SpringMultipartFile 接口,允许你将Apache Commons FileUploadFileItem 对象作为 SpringMultipartFile 来使用。

CommonsMultipartFile实现

以maven的方式如何引入CommonsMultipartFile

<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>

实现代码:

private static MultipartFile convertByteToMultipartFile(byte[] imageBytes,String fileName) {if (Objects.isNull(imageBytes)) {log.error("获取微信小程序码图片信息失败,接口返回为空");throw new CustomException("由于输入byte数组为空,导致转换为MultipartFile失败");}String contentType = "image/jpeg";FileItem item;try {FileItemFactory factory = new DiskFileItemFactory();item = factory.createItem("file", contentType, false, fileName);try (ByteArrayOutputStream bos = new ByteArrayOutputStream(imageBytes.length);OutputStream os = item.getOutputStream()) {bos.write(imageBytes);os.write(bos.toByteArray());}return new CommonsMultipartFile(item);} catch (IOException e) {log.error("转换微信小程序码图片信息为MultipartFile时发生错误", e);throw new CustomException("转换过程中发生错误", e);}
}

byte[]转File

byte[]File的实现方式更多一些,很多第三方高质量的轮子提供了均对应的方法,无需自行实现,调用API即可,下文以HuTool``与Apache Commons lang3举例。

前置条件-获取文件byte[]

以下代码从本地读取文件并转为byte[]用于模拟业务逻辑。

    /*** 将文件内容读取到字节数组中。** @param filePath 文件路径* @return 字节数组,如果文件不存在或读取过程中发生错误,则返回null*/public static byte[] getFileBytes(String filePath) {File file = new File(filePath);// 检查文件是否存在if (!file.exists()) {System.out.println("文件不存在");return null;}try (// 使用try-with-resources语句自动管理资源FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel()) {// 分配一个ByteBuffer,大小为文件的大小ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileChannel.size());// 从文件通道读取数据到ByteBufferfileChannel.read(byteBuffer);// 反转ByteBuffer的limit和position,使得可以通过array()方法获取数据byteBuffer.flip();// 返回包含文件数据的字节数组return byteBuffer.array();} catch (IOException e) {// 如果发生IO异常,记录错误日志并返回nulle.printStackTrace(); // 这里假设e.printStackTrace()是日志记录的一种形式return null;}}
}

以Hutool的方式

引入Hutool

以maven坐标的方式:

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version>
</dependency>

以Gradle的方式:

implementation 'cn.hutool:hutool-all:5.8.26'

具体请参考官方文档:

Hutool快速入门

byte[] data = getFileBytes("src/main/resources/banner.txt");
// 指定要创建的文件路径
String filePath = "/path/to/your/output/file";
// 使用HuTool将byte数组写入到文件
File file = FileUtil.writeBytes(data, filePath);

以Apache Commons IO的方式

引入Apache Commons IO

以maven坐标的形式:

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.16.1</version>
</dependency>

以Gradle的形式:

implementation 'commons-io:commons-io:2.16.1'

代码实现:

public static void main(String[] args) {try {//业务逻辑中获取到的byte[]byte[] fileBytes = getFileBytes("src/main/resources/banner.txt");//目标文件String outputFilePath = "src/main/resources/banner22.txt";File outputFile = writeBytesToFile(outputFilePath, fileBytes);log.error("文件写入成功,输出文件路径: {}", outputFile.getAbsolutePath());} catch (IOException e) {log.error("转换错误", e);}
}public static File writeBytesToFile(String filePath, byte[] fileBytes) throws IOException {File outputFile = new File(filePath);FileUtils.writeByteArrayToFile(outputFile, fileBytes);// 返回File对象return outputFile;
}

MultipartFile与File互转

字节数组可以转换为File,同样也可以转换为MultipartFile,那么MultipartFileFile之间的互转可以利用byte[]作为中间桥梁。

MultipartFile转File

MultipartFile接口提供了getInputStream()方法,你可以使用这个方法来读取文件内容,并将它们写入到一个新的File对象中。

public class MultipartFileToFileConverter {public static File convert(MultipartFile multipartFile, String filePath) throws IOException {// 检查MultipartFile是否为空if (multipartFile == null || multipartFile.isEmpty()) {throw new IOException("文件为空");}// 创建File对象File file = new File(filePath);// 使用try-with-resources语句自动关闭资源try (InputStream inputStream = multipartFile.getInputStream();FileOutputStream outputStream = new FileOutputStream(file)) {// 将输入流中的数据写入到输出流(即文件)中byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}// 返回创建的File对象return file;}
}

File转MultipartFile

FileMultipartFile同样需要依赖于CommonsMultipartFile

public class FileToMultipartFileConverter {public static MultipartFile convert(File file) throws IOException, FileUploadException {// 创建FileItemFactory实例FileItemFactory factory = new DiskFileItemFactory();// 创建一个FileItem来包装File对象org.apache.commons.fileupload.FileItem fileItem = factory.createItem("file", // 表单字段名,可以自定义"application/octet-stream", // 内容类型true, // 是否使用临时文件存储上传的数据file.getName() // 文件名);// 将File对象的内容写入到FileItem中fileItem.write(new File(fileItem.getName()));// 使用CommonsMultipartFile来包装FileItemreturn new DiskFileItem(fileItem).getStoreLocation();}
}

星空不问赶路人,岁月不负有心人。

wallhaven-p9z9qm (1).jpg

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s学习笔记(一)

configMap 一般用来存储配置信息 创建configMap 从文件中获取信息创建&#xff1a;kubectl create configmap my-config --from-file/tmp/k8s/user.txt 直接指定信息&#xff1a; kubectl create configmap my-config01 --from-literalkey1config1 --from-literalkey2confi…

深度学习之计算机视觉

神经网络简介 全连接层和卷积层的根本区别在于权重在中间层中彼此连接的方式。图5.1描述了全连接层或线性层是如何工作的。 在计算机视觉中使用线性层或全连接层的最大挑战之一是它们丢失了所有空间信息&#xff0c;并且就全连接层使用的权重数量而言复杂度太高。例如&#xf…

鸿蒙Harmony实战—通过登录Demo了解ArkTS

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集。 ArkTS在TS的基础上主要扩展了如下能力&#xff1a; 基本语法&#xff1a;ArkTS定义…

最新版Cisco Packet Tracer思科模拟器Windows版本64位下载

Cisco Packet Tracer是思科公司推出的一款网络仿真工具&#xff0c;主要用于网络教学、培训和实验。它提供了一个真实的网络环境模拟平台&#xff0c;让用户可以设计、构建和调试网络&#xff0c;以及进行实时互动&#xff0c;从而帮助用户理解和实践网络技术。 通过 Cisco Pa…

Unity和UE免费领恐怖书本头怪兽角色模型恐怖或奇幻游戏monster适合FPS类型PBR202406202143

Unity和UE免费领恐怖书本头怪兽角色模型恐怖或奇幻游戏monster适合FPS类型PBR202406202143 Unity恐怖书本头怪兽角色模型&#xff1a;https://prf.hn/l/zpBqgVl UE恐怖书本头怪兽角色模型&#xff1a;https://prf.hn/l/4PzY1Qy 作者其他资产&#xff1a;https://prf.hn/l/0…

Fastjson漏洞之CVE-2022-25845

前言&#xff1a; 针对Fastjson之前已经介绍了&#xff0c;这里就不再重复了&#xff0c;漏洞CVE-2017-18349只能用来攻击>1.2.24版本的&#xff0c;CVE-2022-25845属于CVE-2017-18349的升级版&#xff0c;但是目前仅影响到1.2.83以下版本。CVE-2022-25845本质上是绕过了名…

SpringBoot | 实现邮件发送

运行环境&#xff1a; IntelliJ IDEA 2022.2.5 (Ultimate Edition) (注意&#xff1a;idea必须在2021版本以上&#xff09;JDK17 项目目录&#xff1a; 该项目分为pojo,service,controller,utils四个部分&#xff0c; 在pojo层里面写实体内容&#xff08;发邮件需要的发件人邮…

【etcd】etcd单机安装及简单操作

https://blog.csdn.net/Mr_XiMu/article/details/125026635 https://blog.csdn.net/m0_73192864/article/details/136509244 etcd在生产环境中一般为集群方式部署 etcd使用的2个默认端口号&#xff1a;2379和2380 2379&#xff1a;用于客户端通信(类似于sqlserver的1433&#x…

vscode卡顿问题处理(vue-official插件)

vue官方扩展由volar升级为vue-official&#xff0c;部分人的ide会变得非常卡顿&#xff0c;这是由于vscode本身一些问题导致&#xff0c;如下图作者解释&#xff1a; 解决方式&#xff1a; 通过禁用Hybrid模式&#xff0c;不使用tsserver来接管语言支持&#xff0c;卡顿会缓解…

CSS文本超限后使用省略号代替

方案一&#xff1a; 只显示一行&#xff0c;超限后使用省略号代替 .detail {overflow: hidden;text-overflow: ellipsis;white-space: nowrap; }方案二&#xff1a; 显示多行&#xff0c;到最后一行还没有显示完&#xff0c;则最后一行多出来的部分使用省略号代替。 .detai…

Vulhub——Log4j、solr

文章目录 一、Log4j1.1 Apache Log4j2 lookup JNDI 注入漏洞&#xff08;CVE-2021-44228&#xff09;1.2 Apache Log4j Server 反序列化命令执行漏洞&#xff08;CVE-2017-5645&#xff09; 二、Solr2.1 Apache Solr 远程命令执行漏洞&#xff08;CVE-2017-12629&#xff09;2.…

异步任务使用场景与实践

异步任务使用场景 根据同步/异步方式划分场景&#xff0c;各场景下常用的技术方案如下&#xff1a; 方式实现特点缺点同步HTTP RPC Cache etc.指标&#xff1a;RT、QPS、TPS、缓存命中率 等&#xff1b; 关注&#xff08;准&#xff09;实时数据&#xff0c;用户可交互1. 处…

javascript--类型检测 type of 和 instanceof

类型判断 1、typeof2、instanceof**instanceof 的原理** 3、constructor 1、typeof typeof在检测null、object、array、data的结果中都是object&#xff0c;所以无法用来区分这几个类型的区别。 <script>let a ["123",123,false,true,Symbol(1),new Date(),n…

ubuntu18.04 安装HBA

HBA是一个激光点云层级式的全局优化的程序&#xff0c;他的论文题目是&#xff1a;HBA: A Globally Consistent and Efficient Large-Scale LiDAR Mapping Module&#xff0c;对应的github地址是&#xff1a;HKU-Mars-Lab GitHub 学习本博客&#xff0c;可以学到gtsam安装&am…

系统凭据钓鱼揭秘

背景 在进行内网横向移动时&#xff0c;通常会尝试抓取目标机器上的登录哈希和密码。但是&#xff0c;这种方法并不总是可行&#xff0c;因为有些目标机器可能没有这些信息&#xff0c;或者这些信息已经被清除或加密。因此&#xff0c;黑客们开始模拟Windows系统环境中的身份认…

智慧学习实践系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;企业管理&#xff0c;任务管理&#xff0c;公告管理&#xff0c;菜单管理&#xff0c;用户管理&#xff0c;基础数据管理 企业账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;任务…

视频融合共享平台LntonCVS视频监控安防系统运用多视频协议建设智慧园区方案

智慧园区&#xff0c;作为现代化城市发展的重要组成部分&#xff0c;不仅推动了产业的升级转型&#xff0c;也成为了智慧城市建设的核心力量。随着产业园区之间的竞争日益激烈&#xff0c;如何打造一个功能完善、智能化程度高的智慧园区&#xff0c;已经成为了业界广泛关注的焦…

多线程(Lock锁,死锁,等待唤醒机制,阻塞队列,线程池)

Lock锁 虽然我们可以理解同步代码块和同步方法的锁对象问题但是我们并没有直接看到在哪里加上了锁&#xff0c;在哪里释放了锁为了更清晰的表达如何加锁和释放锁&#xff0c;JDK5以后提供了一个新的锁对象Lock Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操…

数据可视化作业二:中国城市地铁数据可视化

目录 作业要求 一、绘制每个城市站点数量柱状图&#xff08;降序排列&#xff09; 1.1 每个城市站点数量统计 1.1.1 代码展示 1.1.2 统计结果展示 1.2 柱状图绘制 1.2.1 代码实现 1.2.2 绘制结果 二、绘制上海市地铁线路站点数饼状图 2.1 数据处理 2.2 代码实现 2.3…

实际二分搜索(写出函数,再用二分搜索法找左右边界 画图理解

实际二分搜索&#xff08;写出函数&#xff0c;再用二分搜索法找左右边界 看到最大值的最小化&#xff0c;左边界&#xff0c;最小化的最大值&#xff0c;右边界 画图理解 爱吃香蕉的珂珂 class Solution {public int minEatingSpeed(int[] piles, int h) {int left1,right10…