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

news2024/10/23 4:57:14

目录

需求背景

当你需要将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());
            // 从文件通道读取数据到ByteBuffer
            fileChannel.read(byteBuffer);
            // 反转ByteBuffer的limit和position,使得可以通过array()方法获取数据
            byteBuffer.flip();
            // 返回包含文件数据的字节数组
            return byteBuffer.array();
        } catch (IOException e) {
            // 如果发生IO异常,记录错误日志并返回null
            e.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来包装FileItem
        return new DiskFileItem(fileItem).getStoreLocation();
    }
}

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

wallhaven-p9z9qm (1).jpg

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

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

相关文章

剑指offer 算法题(数组中重复的数据)

剑指offer 第一题 去力扣里测试算法 思路一&#xff1a; 排序后&#xff0c;前一个与后一个相比是否相同。 class Solution { public:vector<int> findDuplicates(vector<int>& nums) {sort(nums.begin(), nums.end());int n 0;int len nums.size();vect…

如何设计一个点赞系统

首先我们定义出一个点赞系统需要对外提供哪些接口&#xff1a; 1.用户对特定的消息进行点赞&#xff1b; 2.用户查看自己发布的某条消息点赞数量以及被哪些人赞过&#xff1b; 3.用户查看自己给哪些消息点赞过&#xff1b; 这里假设每条消息都有一个message_id, 每一个用户都…

文件防篡改监控工具 - WGCLOUD全面介绍

WGCLOUD是一款优秀的运维监控软件&#xff0c;免费、轻量、高效&#xff0c;部署容易&#xff0c;上手简单&#xff0c;对新手非常友好 WGCLOUD部署完成后&#xff0c;点击菜单【文件防篡改】&#xff0c;可以看到如下页面 我们点击【添加】按钮&#xff0c;输入监控文件的信息…

python之Bible快速检索器

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! python之Bible快速检索器 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; 助力快…

【网络安全的神秘世界】已解决Failed to start proxy service on 127.0.0.1:8080

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 解决burpsuite无法在 127.0.0.1&#xff1a;8080 上启动代理服务端口被占用以及抓不到本地包的问题 Burpsuite无法启动proxy…

ISSN和CN到底有什么不同呢?

在学术出版领域&#xff0c;我们常常会遇到各种标识码&#xff0c;其中ISSN和CN无疑是两个最为常见的。尽管它们都是用于标识出版物的重要信息&#xff0c;但两者在定义、功能和应用上却有着显著的区别。那么&#xff0c;ISSN和CN到底有什么不同呢&#xff1f;接下来&#xff0…

深度解析RocketMq源码-持久化组件(四) CommitLog

1.绪论 commitLog是rocketmq存储的核心&#xff0c;前面我们介绍了mappedfile、mappedfilequeue、刷盘策略&#xff0c;其实commitlog的核心组件我们基本上已经介绍完成。 2.commitLog的组成 commitLog的核心其实就是MqppedFilequeue&#xff0c;它本质上就是多个mappedFile…

图像数字化基础

一、像素 1、获取图像指定位置的像素 import cv2 image cv2.imread("E:\\images\\2.png") px image[291,218] print("坐标(291,218)上的像素的BGR值是&#xff1a;",px) &#xff08;1&#xff09;RGB色彩空间 R通道&#xff1a;红色通道 G通道&…

LVS(Linux Virtual Server)集群,(1)NAT模式

Cluster&#xff1a;集群&#xff0c;为了解决某个特定问题将多台计算机组合起来形成的单个系统。 集群分为三种类型&#xff1a; LB(Load Balancing)&#xff0c;负载均衡&#xff0c;多个主机组成&#xff0c;每个主机只承担一部分访问请求 HA(High Availiablity)&#xf…

网工内推 | H3C工程师,大专可投,无责底薪加提成

01 内蒙古华贸信息科技有限公司 &#x1f537;招聘岗位&#xff1a;H3C工程师 &#x1f537;岗位职责&#xff1a; 1、负责核心网络的7*24小时网络运维&#xff0c;可持续对网络进行优化&#xff0c;提供高质量的网络服务&#xff1b; 2、能够独立运维高端核心设备和楼层接入网…

Premiere Pro 关键帧的运用(光盘滚入盘盒)

制作“光盘滚入盘盒”效果&#xff0c;步骤如下&#xff1a; 1.新建项目>新建序列&#xff0c;项目名称为“光盘滚入盘盒”&#xff0c;序列设置如下图所示。 2.导入素材到项目面板中。 3.新建“颜色遮罩 ”。在项目面板中&#xff0c;右键【新建项目】-【颜色遮罩】-【视…

idea2023开发插件入门

idea2023开发插件入门 创建工程 通过 idea plugin 来创建工程 修改 开发语言 默认创建的工程是用scala开发的&#xff0c;但是我不会&#xff0c;就会java,所以改成java创建 build.gradle.kt 为 build.gradlesettings.gradle.kt 为 settings.gradle build.gradle修改为以…

css实现多行文本的展开收起

背景 在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景&#xff1a; 那么&#xff0c;如何通过纯css实现这样的效果呢&#xff1f; 实现的难点 &#xff08;1&#xff09;位于多行文本右下角的 展开收起按钮。 &#xff08;2&#xff09;展开和收起两种状态的…

Linux--视频推流及问题

方案一&#xff1a; mjpg-streamer,它运行在ARM板上 在手机上使用浏览器直接观看视频 方案二&#xff1a; 推流端&#xff08;Fmpeg&#xff09;--rtmp-->Nginx&#xff08;流媒体服务器&#xff09;--rtmp/httpflv/hls-->浏览器、播放器 此篇文章记录方案二的具体细…

理解HTTP请求格式

HTTP概念 HTTP全称HyperTextTransfer Protocol(超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议&#xff1b;HTTP是一个客户端&#xff08;用户&#xff09;和服务端&#xff08;网站&#xff09;之间请求和响应的标准。 HTTP 协议是以 ASCII 码传输&…

IDEA 运行 ‘xxx‘ 时出错. 命令行过长. 通过 JAR 清单或通过类路径文件缩短命令行,然后重新运行.

IDEA 运行 ‘xxx’ 时出错. 命令行过长. 通过 JAR 清单或通过类路径文件缩短命令行&#xff0c;然后重新运行. 目录 IDEA 运行 xxx 时出错. 命令行过长. 通过 JAR 清单或通过类路径文件缩短命令行&#xff0c;然后重新运行.报错解决方案jar清单jar清单 报错原因&#xff1a;1.使…

可预约上门服务的在线DIY预约小程序源码系统 带完整的安装代码包以及搭建教程

系统概述 这款可预约上门服务的在线 DIY 预约小程序源码系统是为满足各类上门服务需求而设计的。它允许用户通过小程序方便地预约各种服务&#xff0c;如家政服务、维修服务、美容美发服务等。同时&#xff0c;商家可以在后台管理系统中方便地管理预约信息、服务项目、员工信息…

数据链路层知识分享【计算机网络】【以太网帧 | MTU的影响 | ARP技术】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 前文 一&#xff0c; 以…

贝叶斯优化、高斯过程相关概念总结

目录 贝叶斯优化 高斯过程 采集函数 贝叶斯优化 贝叶斯优化 &#xff5c; 黑盒优化全局最优方法 &#xff5c; Bayesian Optimization_哔哩哔哩_bilibili 贝叶斯优化用于解决寻找某个函数的最大值/最小值&#xff0c;在自变量维度比较小时(<20)表现的非常好。 适用…

嵌入式系统软件开发环境_2.一般架构

1.Eclipse框架 嵌入式系统软件开发环境是可帮助用户开发嵌入式软件的一组工具的集合&#xff0c;其架构的主要特征离不开“集成”问题&#xff0c;采用什么样的架构框架是决定开发环境优劣主要因素。Eclipse框架是当前嵌入式系统软件开发环境被普遍公认的一种基础环境框架。目…