4.2 媒资管理模块 - 项目搭建、minio文件系统

文章目录

  • 一、搭建媒资服务工程
    • 1.1 media-api 工程
      • 1.1.1 bootstrap.yaml
      • 1.1.2 Maven
      • 1.1.3 Nacos
    • 1.2 media-service 工程
      • 1.2.1 bootstrap.yaml
      • 1.2.2 Maven
      • 1.2.3 Nacos
      • 1.2.4 分页插件
    • 1.3 media-model 工程
      • 1.3.1 QueryMediaParamsDto
      • 1.3.2 MediaFiles
      • 1.3.3 MediaProcess
      • 1.3.4 MediaProcessHistory
      • 1.3.5 MqMessage
      • 1.3.6 MqMessageHistory
    • 1.4 xuecheng-plus-media
      • 1.4.1 Maven
    • 1.5 启动工程
  • 二、分布式文件系统
    • 2.1 文件系统介绍
    • 2.2 分布式文件系统介绍
      • 2.2.1 NFS 网络文件系统
      • 2.2.2 GFS 可扩展分布式文件系统
      • 2.2.3 HDFS
      • 2.2.4 云计算厂家
  • 三、MinIo文件系统
    • 3.1 介绍
    • 3.2 使用
    • 3.3 Docker环境测试
    • 3.4 SDK
      • 3.4.1 Maven版本
      • 3.4.2 上传文件
      • 3.4.3 删除文件
      • 3.4.4 查询文件
      • 3.4.5 设置多层目录
      • 3.4.6 设置媒体文件类型

一、搭建媒资服务工程

可以参照下面两篇文章进行搭建

3.1 内容管理模块 - 工程搭建、课程查询、配置Swagger、数据字典-CSDN博客

4.1 媒资管理模块 - Nacos与Gateway搭建-CSDN博客

工程结构如下所示

image-20231219000227543

image-20231219000742157

并且创有如下所示的媒资数据库

image-20231218235909056

1.1 media-api 工程

1.1.1 bootstrap.yaml

#微服务配置
spring:application:name: media-apicloud:nacos:server-addr: 192.168.101.65:8848discovery:namespace: ${spring.profiles.active}group: xuecheng-plus-projectconfig:namespace: ${spring.profiles.active}group: xuecheng-plus-projectfile-extension: yamlrefresh-enabled: trueextension-configs:- data-id: media-service-${spring.profiles.active}.yamlgroup: xuecheng-plus-projectrefresh: trueshared-configs:- data-id: swagger-${spring.profiles.active}.yamlgroup: xuecheng-plus-commonrefresh: true- data-id: logging-${spring.profiles.active}.yamlgroup: xuecheng-plus-commonrefresh: trueprofiles:active: dev

1.1.2 Maven

我们这里的swagger用的下篇网站中的坐标,解释也在下篇文章中

3.1 内容管理模块 - 工程搭建、课程查询、配置Swagger、数据字典-CSDN博客

<parent><artifactId>xuecheng-plus-media</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-media-api</artifactId>
<name>xuecheng-plus-media-api</name>
<description>xuecheng-plus-media-api</description><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-media-model</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-media-service</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!--cloud的基础环境包--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-context</artifactId></dependency><!-- Spring Boot 的 Spring Web MVC 集成 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!-- Spring Boot 对 LocalDateTimeboot-starter-web自动引入--><!-- <dependency><groupId>com.fasterxml.jackson.module</groupId><artifactId>jackson-module-parameter-names</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jdk8</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId></dependency>--><!--<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>--><!-- 排除 Spring Boot 依赖的日志包冲突 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- Spring Boot 集成 log4j2 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><!-- Spring Boot 集成 swagger --><!--swagger--><dependency><groupId>com.spring4all</groupId><artifactId>swagger-spring-boot-starter</artifactId></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>1.5.22</version></dependency></dependencies>

1.1.3 Nacos

server:servlet:context-path: /mediaport: 63050

1.2 media-service 工程

1.2.1 bootstrap.yaml

spring:application:name: media-servicecloud:nacos:server-addr: 192.168.101.65:8848discovery:namespace: ${spring.profiles.active}group: xuecheng-plus-projectconfig:namespace: ${spring.profiles.active}group: xuecheng-plus-projectfile-extension: yamlrefresh-enabled: trueshared-configs:- data-id: logging-${spring.profiles.active}.yamlgroup: xuecheng-plus-commonrefresh: true#profiles默认为devprofiles:active: dev

1.2.2 Maven

<parent><artifactId>xuecheng-plus-media</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-media-service</artifactId>
<name>xuecheng-plus-media-service</name>
<description>xuecheng-plus-media-service</description><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-media-model</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- mybatis plus的依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- Spring Boot 集成 Junit --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 排除 Spring Boot 依赖的日志包冲突 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- Spring Boot 集成 log4j2 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency></dependencies>

1.2.3 Nacos

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.101.65:3306/xcplus_media?serverTimezone=UTC&userUnicode=true&useSSL=false&username: rootpassword: mysqlcloud:config:override-none: true

1.2.4 分页插件

/*** <P>* Mybatis-Plus 配置* </p>*/
@Configuration
@MapperScan("com.xuecheng.media.mapper")
public class MybatisPlusConfig {/*** 新的分页插件* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false* 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

1.3 media-model 工程

image-20231219001323313

1.3.1 QueryMediaParamsDto

/*** @description 媒资文件查询请求模型类*/
@Data
@ToString
public class QueryMediaParamsDto {@ApiModelProperty("媒资文件名称")private String filename;@ApiModelProperty("媒资类型")private String fileType;@ApiModelProperty("审核状态")private String auditStatus;
}

1.3.2 MediaFiles

/*** 媒资信息*/
@Data
@TableName("media_files")
public class MediaFiles implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.ASSIGN_ID)private String id;/*** 机构ID*/private Long companyId;/*** 机构名称*/private String companyName;/*** 文件名称*/private String filename;/*** 文件类型(文档,音频,视频)*/private String fileType;/*** 标签*/private String tags;/*** 存储目录*/private String bucket;/*** 存储路径*/private String filePath;/*** 文件标识*/private String fileId;/*** 媒资文件访问地址*/private String url;/*** 上传人*/private String username;/*** 上传时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 修改时间*/@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime changeDate;/*** 状态,1:未处理,视频处理完成更新为2*/private String status;/*** 备注*/private String remark;/*** 审核状态*/private String auditStatus;/*** 审核意见*/private String auditMind;/*** 文件大小*/private Long fileSize;}

1.3.3 MediaProcess

@Data
@ToString
@TableName("media_process")
public class MediaProcess implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 文件标识*/private String fileId;/*** 文件名称*/private String filename;/*** 存储源*/private String bucket;private String filePath;/*** 状态,1:未处理,视频处理完成更新为2*/private String status;/*** 上传时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 完成时间*/private LocalDateTime finishDate;/*** 媒资文件访问地址*/private String url;/*** 失败原因*/private String errormsg;/*** 失败次数*/private int failCount;}

1.3.4 MediaProcessHistory

@Data
@TableName("media_process_history")
public class MediaProcessHistory implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 文件标识*/private String fileId;/*** 文件名称*/private String filename;/*** 存储源*/private String bucket;private String filePath;/*** 状态,1:未处理,视频处理完成更新为2*/private String status;/*** 上传时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 完成时间*/private LocalDateTime finishDate;/*** 媒资文件访问地址*/private String url;/*** 失败原因*/private String errormsg;/*** 失败次数*/private int failCount;}

1.3.5 MqMessage

@Data
@TableName("mq_message")
public class MqMessage implements Serializable {private static final long serialVersionUID = 1L;/*** 消息id*/private String id;/*** 消息类型代码*/private String messageType;/*** 关联业务信息*/private String businessKey1;/*** 关联业务信息*/private String businessKey2;/*** 关联业务信息*/private String businessKey3;/*** 消息队列主机*/private String mqHost;/*** 消息队列端口*/private Integer mqPort;/*** 消息队列虚拟主机*/private String mqVirtualhost;/*** 队列名称*/private String mqQueue;/*** 通知次数*/private Integer informNum;/*** 处理状态,0:初始,1:成功,2:失败*/private Integer state;/*** 回复失败时间*/private LocalDateTime returnfailureDate;/*** 回复成功时间*/private LocalDateTime returnsuccessDate;/*** 回复失败内容*/private String returnfailureMsg;/*** 最近通知时间*/private LocalDateTime informDate;}

1.3.6 MqMessageHistory

@Data
@TableName("mq_message_history")
public class MqMessageHistory implements Serializable {private static final long serialVersionUID = 1L;/*** 消息id*/private String id;/*** 消息类型代码*/private String messageType;/*** 关联业务信息*/private String businessKey1;/*** 关联业务信息*/private String businessKey2;/*** 关联业务信息*/private String businessKey3;/*** 消息队列主机*/private String mqHost;/*** 消息队列端口*/private Integer mqPort;/*** 消息队列虚拟主机*/private String mqVirtualhost;/*** 队列名称*/private String mqQueue;/*** 通知次数*/private Integer informNum;/*** 处理状态,0:初始,1:成功,2:失败*/private Integer state;/*** 回复失败时间*/private LocalDateTime returnfailureDate;/*** 回复成功时间*/private LocalDateTime returnsuccessDate;/*** 回复失败内容*/private String returnfailureMsg;/*** 最近通知时间*/private LocalDateTime informDate;}

1.4 xuecheng-plus-media

1.4.1 Maven

<parent><artifactId>xuecheng-plus-parent</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version><relativePath>../xuecheng-plus-parent</relativePath>
</parent>
<artifactId>xuecheng-plus-media</artifactId>
<name>xuecheng-plus-media</name>
<description>xuecheng-plus-media</description>
<packaging>pom</packaging><modules><module>xuecheng-plus-media-api</module><module>xuecheng-plus-media-service</module><module>xuecheng-plus-media-model</module>
</modules>

1.5 启动工程

image-20231219002708605

相当的帮!

二、分布式文件系统

我们需要一种方案能支持存储大量的视频、图片,所以我们需要一个分布式文件系统

分布式文件系统就是海量用户查阅海量文件的方案

2.1 文件系统介绍

文件系统是负责管理和存储文件的系统软件,操作系统通过文件系统提供的接口去存取文件,用户通过操作系统访问磁盘上的文件

文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Fash的固态硬盘)或分区上的文件的方法和数据结构,即在存储设备上组织文件的方法

操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统

文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性

从系统角度来看,文件系统是对文件存储没备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。

具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等

常见的文件系统:FAT16/FAT32、NTFS(Windows的文件操作系统)、HFS、UFS、APFS、XFS、Ext4等
image-20231219004234030

比如HDD、SSD、CO ROM是我们的磁盘,应用软件是微信

那我们从磁盘上读取文件需要经历操作系统、文件系统、驱动程序

假如说没有文件系统,我们不可能以一个目录的形式查看磁盘中的文件

image-20231219004040628

总结:文件系统就是方便对磁盘的文件进行管理的一套文件系统

2.2 分布式文件系统介绍

原来我们整个项目是单体架构,内容管理、媒资管理、系统管理都在一个服务内

而现在把内容管理、媒资管理、系统管理都拆分成了不同的微服务,而这些微服务都会独立的进行部署,这种独立部署的方式就叫分布式方式

为什么要将文件系统进行分布式呢

如果我们想处理大量的视频文件,一台计算机的能力是有限的,所以我们通过网络将若干计算机组织起来共同去存储海量的文件(首先是存储能力提高了),去接收海量用户的请求,这些组织起来的计算机通过网络进行通信

image-20231219005130687

好处

  • 一台计算机的文件系统处理能力扩充到多台计算机同时处理。

  • 一台计算机挂了还有另外副本计算机提供数据。

  • 每台计算机可以放在不同的地域,这样用户就可以就近访问,提高访问速度

2.2.1 NFS 网络文件系统

image-20231219010046527

远程的计算机里面存了一些文件,客户端可以通过网络访问远程计算机

假如本机有C、D两个驱动器磁盘(没有E盘),客户端通过网络连接访问远程计算机后可以将远程计算机上的文件映射到本地的E盘,访问E盘的文件其实就是相当于访问远程计算机中的文件

远程计算机的文件会映射到本地计算机的一个磁盘驱动器内

image-20231219010108595

特点

  • 在客户端上映射NFS服务器的驱动器

  • 客户端通过网络访问NFS服务器的硬盘完全透明

2.2.2 GFS 可扩展分布式文件系统

架构图

image-20231219010741753

image-20231219010752287

GFS client:客户端

GFS master: master,会将文件信息存储在此处,文件的信息叫做元数据(文件的格式、大小),之后会将文件分成若干块,按照一定的算法存储在不同分块服务器

GFS chunkserver:分块服务器,是有多台的

当客户端去查询文件的时候,master很清楚分块存储在哪些分块服务器里,然后master会将文件信息的分块找到并合并然后返回

2.2.3 HDFS

与GFS相似

HDFS,是Hadoop Distributed File System的简称,是Hadoop抽象文件系统的一种实现

HDFS是一个高度容错性的系统,适合部署在廉价的机器上。

HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。

HDFS的文件分布在集群机器上,同时提供副本进行容错及可靠性保证。

例如客户端写入读取文件的直接操作都是分布在集群各个机器上的,没有单点性能压力

架构图

image-20231219011355751

Namenode存储文件的原信息,之后会进行分块

客户端查询的时候Namenode会对分块进行组装合并然后返回

2.2.4 云计算厂家

比如阿里云对象存储服务

官方网站:https://www.aliyun.com/product/oss

Mybatis 案例 —— 文件上传OSS_mybatis文件上传-CSDN博客

三、MinIo文件系统

下载地址:https://dl.min.io/server/minio/release/

3.1 介绍

MinIO 是一个非常轻量的服务,可以很简单的和其他应用的结合使用,它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等

特点就是轻量,使用简单,功能强大,支持各种平台,单个文件最大5TB,兼容 Amazon S3接口,提供了 Java、Python、GO等多版本SDK支持

官网:https://min.io

中文:https://www.minio.org.cn/,http://docs.minio.org.cn/docs/

MinIO集群采用去中心化共享架构,每个结点是对等关系,通过Nginx可对MinIO进行负载均衡访问

什么是去中心化

在大数据领域,通常的设计理念都是无中心和分布式。

哪一个结点都可以当老大,下面的四个结点都不是主节点

去中心化有什么好处

容错性更强,避免了单点故障。假如说某个结点挂掉后,不会影响整个集群的访问,并且当挂掉的结点重启后会迅速的把结点上的文件给恢复

一个结点两块硬盘,四个结点八块硬盘

当我们上传文件的时候,会把文件分成若干块

如果是下面这个模式的话是分成4个数据块(文件分为了4份)和4个校验块存(校验块是为了文件丢失时恢复)放在下面的结点上

image-20231220221809461

Minio使用纠删码技术来保护数据,它是一种恢复丢失和损坏数据的数学算法,它将数据分块冗余的分散存储在各各节点的磁盘上,所有的可用磁盘组成一个集合,上图由8块硬盘组成一个集合,当上传一个文件时会通过纠删码算法计算对文件进行分块存储,除了将文件本身分成4个数据块,还会生成4个校验块,数据块和校验块会分散的存储在这8块硬盘上。

使用纠删码的好处是即便丢失一半数量(N/2)的硬盘,仍然可以恢复数据

比如上边集合中有4个以内的硬盘损害仍可保证数据恢复,不影响上传和下载,如果多于一半的硬盘坏了则无法恢复

3.2 使用

  • 准备4个数据结点

image-20231220223537246

  • 在下载的minio.exe文件下运行MinIo
minio.exe server D:\zhangjingqi\Note\xuecheng\Note\data1  D:\zhangjingqi\Note\xuecheng\Note\data2  D:\zhangjingqi\Note\xuecheng\Note\data3  D:\zhangjingqi\Note\xuecheng\Note\data4

如果是通过虚拟机启动四个minio,每个虚拟机提供一个minio服务的话,上面的路径就是"http:\\"开头的

  • 运行结果

    有用户名和密码,也有访问地址 http://192.168.1.33:9000

image-20231220223827756

  • 登录

image-20231220224352370

  • 创建一个Buckets,可以理解为创建一个目录

image-20231220224500053

image-20231220224554800

创建完成之后是下面这个样子

image-20231220224617748

创建完成之后目录中也有“testbuckets”目录

image-20231220224712237

  • 传输文件

image-20231220224916404

再查看文件夹

image-20231220225017288

image-20231220224959278

image-20231220225139094

image-20231220225150119

  • 删除节点data1

    然后测试一下是否影响读取和写入

image-20231220225306520

再传入文件,也是没什么问题的

image-20231220225350888

然后我们发现又把数据同步到data1了

image-20231220225521912

  • 删除data1和data2

依然可以稳定执行

  • 删除data1、data2、data3时,便不可以

    此时页面就会进不去,更别说传文件了

3.3 Docker环境测试

开发阶段和生产阶段统一使用Docker下的MINIO。

虚拟机中已安装了MinIO的镜像和容器,执行sh /data/soft /restart.sh启动Docker下的MinIO

启动完成登录MinIO查看是否正常。

访问http://192.168.101.65:9000

mediafiles: 普通文件

video:视频文件

image-20231220230355449

3.4 SDK

MinIO提供多个语言版本SDK的支持,下边找到java版本的文档:

地址:https://docs.min.io/docs/java-client-quickstart-guide.html

最低需求Java 1.8或更高版本

首先要创建一个testbucket

image-20231220233911630

修改访问权限

image-20231220234002955

改成public

如果是private的话,是通过接口下载不到这里面的文件

image-20231220234121726

3.4.1 Maven版本

media-service工程添加此依赖

<!--minio依赖-->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version>
</dependency>
<!--http依赖,springboot默认使用的http,发送http请求-->
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.8.1</version>
</dependency>

3.4.2 上传文件

其实上传视频也要做一个完整性校验

怎么搞?

上传上去后再下载下载做一个完整性校验

/*** 测试minio的SDK*/
@SpringBootTest
public class MinioTest {MinioClient minioClient =MinioClient.builder()//这个地方是运行minio后展示的地址.endpoint("http://192.168.101.65:9000")//账号和密码.credentials("minioadmin", "minioadmin").build();@Testpublic void test_upload() {try {// 判断桶testbucket是否存在,如果不存在的话就进创建boolean found =minioClient.bucketExists(BucketExistsArgs.builder().bucket("testbucket").build());if (!found) {// Make a new bucket called 'asiatrip'.minioClient.makeBucket(MakeBucketArgs.builder().bucket("testbucket").build());} else {System.out.println("Bucket 'asiatrip' already exists.");}//minioClient.uploadObject上传文件,需要一个UploadObjectArgs类型参数//上传文件的参数信息: UploadObjectArgs.builder()进行构建minioClient.uploadObject(UploadObjectArgs.builder()//桶,也就是目录.bucket("testbucket")//指定本地文件的路径.filename("E:\\SpringBootApplicationTests.java")//上传到minio中的对象名,上传的文件存储到哪个对象中.object("SpringBootApplicationTestsMinIo")//构建.build());} catch (Exception e) {e.printStackTrace();}}
}

minio中确实存在,很棒

image-20231220235545191

3.4.3 删除文件

    @Testpublic void delete() {try {minioClient.removeObject(RemoveObjectArgs.builder()//桶.bucket("testbucket")//要删除的对象.object("SpringBootApplicationTestsMinIo").build());System.out.println("删除成功");} catch (Exception e) {e.printStackTrace();System.out.println("删除失败");}}

没啦没啦

image-20231221000119833

3.4.4 查询文件

其实是从minio中下载文件

    @Testpublic void getFile() {GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket("testbucket").object("test/SpringBootApplicationTestsMinIo").build();try {//查询远程服务器获取到衣蛾流对象FilterInputStream inputStream = minioClient.getObject(getObjectArgs);//输出流,下载到哪里FileOutputStream outputStream = new FileOutputStream(new File("E:\\TestsMinIo.java"));//import org.apache.commons.io.IOUtils;IOUtils.copy(inputStream, outputStream);//校验文件的完整性,对文件的内容进行md5//对minio上的文件进行MD5摘要算法,对下载下来的文件进行摘要算法,如果两者MD5一样,说明下载的文件是完整的//import org.apache.commons.codec.digest.DigestUtils;//这个参数不要写远程流minioClient.getObject(getObjectArgs),会不稳定或者有问题//String source_md5 = DigestUtils.md5Hex(inputStream);FileInputStream fileInputStream = new FileInputStream(new File("E:\\SpringBootApplicationTests.java"));//我们这个地方是拿到最开始上传到minio的原文件的MD5与从下载下面的文件MD5进行对比String source_md5 = DigestUtils.md5Hex(fileInputStream);String local_md5 = DigestUtils.md5Hex(new FileInputStream(new File("E:\\TestsMinIo.java")));if (source_md5.equals(local_md5)){System.out.println("下载成功");}} catch (Exception e) {e.printStackTrace();}}

image-20231221004917576

image-20231221004926790

3.4.5 设置多层目录

//上传到minio中的对象名,上传的文件存储到哪个对象中
//下面这个是直接在桶下存储文件
.object("SpringBootApplicationTestsMinIo")

设置多层目录

将上传的文件放在test目录下

//下面这个是存储在桶/test/目录下
.object("test/SpringBootApplicationTestsMinIo")

很成功

image-20231221000508368

3.4.6 设置媒体文件类型

设置媒体文件类型

参数是一个String类型org.springframework.http.MediaType类型,里面有需要媒体文件类型

image-20231221001210373

我们也可以引入一个工具包,根据扩展名取mimetype

com.j256.simplemagic.ContentInfoUtil;包下

<!---->
<dependency><groupId>com.j256.simplemagic</groupId><artifactId>simplemagic</artifactId><version>1.17</version>
</dependency>

假如我们不设置的话,会自动识别

ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".mp4");//通用mimeType,字节流String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;if (extensionMatch !=null){mimeType = extensionMatch.getMimeType();}minioClient.uploadObject(UploadObjectArgs.builder()//桶,也就是目录.bucket("testbucket")//指定本地文件的路径.filename("E:\\Tests.mp4")//上传到minio中的对象名,上传的文件存储到哪个对象中//下面这个是存储在桶/test/目录下.object("TestsMinIo")//设置媒体文件类型,可以通过扩展名得到媒体资源类型.contentType(mimeType)//构建.build());

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

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

相关文章

nodejs微信小程序+python+PHP汽车租赁管理网站-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

springboot+vue项目如何在linux上部署

在linux上部署项目&#xff0c;是我们实训项目作业的最后一步&#xff0c;此时我们的项目编码测试已经完成&#xff0c;接下来就需要在服务器上部署上线&#xff0c;那么如何部署上线&#xff0c;接下来我会在虚拟机上的CentOS7系统上实现部署&#xff0c; 一.下载JDK 因为我…

搭建一个高效的Python开发环境

“工欲善其事&#xff0c;必先利其器”&#xff0c;这里我们来搭建一套高效的 Python 开发环境&#xff0c;为后续的数据分析做准备。 关于高效作业&#xff0c;对于需要编写 Python 代码进行数据分析的工作而言&#xff0c;主要涉及两个方面。 1. 一款具备强大的自动完成和错…

Unity-Shader-渲染队列,ZTest,ZWrite

Unity-Shader-渲染队列&#xff0c;ZTest&#xff0c;ZWrite ZTest&#xff08;深度测试&#xff09;和ZWrite&#xff08;深度写入&#xff09;ZTest Less&#xff08;深度小于当前缓存则通过&#xff09;ZTest Greater&#xff08;深度大于当前缓存则通过&#xff09;ZTest L…

Linux--Shell脚本应用实战

实验环境 随着业务的不断发展&#xff0c;某公司所使用的Linux服务器也越来越多。在系统管理和维护过程中&#xff0c;经 常需要编写一些实用的小脚本&#xff0c;以辅助运维工作&#xff0c;提高工作效率。 需求描述 > 编写一个名为getarp.sh的小脚本&#xff0c;记录局域…

宝塔面板Linux服务器CentOS 7数据库mysql5.6升级至5.7版本教程

近段时间很多会员问系统更新较慢&#xff0c;也打算上几个好的系统&#xff0c;但几个系统系统只支持MYSQL5.7版本&#xff0c;服务器一直使用较低的MYSQL5.6版本&#xff0c;为了测试几个最新的系统打算让5.6和5.7并存使用&#xff0c;参考了多个文档感觉这种并存问题会很多。…

第十一节TypeScript Array(数组)

1、描述 数组对象是使用单独的变量名来存储一系列的值。 比如&#xff0c;你现在有一组数据&#xff0c;存单独变量如下&#xff1a; var data1"Android"; var data2"Java"; var data3"Harmony"; 那如果有10、100个这种变量呢&#xff0c;那…

指法练习软件TT

1、说明 这个是90年代后期读书时写的C语言练习软件&#xff0c;模仿当时的打字练习软件。 在技能上使用屏幕直接输出&#xff0c;支持彩色&#xff0c;能够在DOS和Windows98的窗口下运行。 2、主要界面 支持多用户档案&#xff0c;以键盘操作。 进入具体用户档案后&#xff0c…

路由器介绍和命令操作

先来回顾一下上次的内容&#xff1a; ip地址就是由32位二进制数组 二进位数就是只有数字0和1组成 网络位&#xff1a;类似于区号&#xff0c;表示区域作用 主机位&#xff1a;类似于号码&#xff0c;表示区域中编号 网络名称&#xff1a;网络位不变&#xff0c;主机位全为0 …

java IO

主要内容 java.io.File类的使用 IO原理及流的分类 文件流 FileInputStream / FileOutputStream / FileReader / FileWriter 缓冲流 BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter 转换流 InputStreamReader / OutputStreamWriter 标准…

树莓派,opencv,Picamera2利用舵机云台追踪人脸(PID控制)

一、需要准备的硬件 Raspiberry Pi 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目…

MP3音乐播放器搜索引擎-窗口实现

在Headers里面添加新文件 想在mainwindow里面通过点击按钮出现这个新的对话框我们应该将新的对话框的头文件添加到mainwindow.h 然后我们可以创建一个AboutADialog对象&#xff0c;模态对话框就是只能对模态对话框进行操作点不了主窗口&#xff0c;非模态对话框则可以&#xff…