上传大文件
1、Promise对象
Promise 对象代表一个异步操作,有三种状态:
- pending: 初始状态,不是成功或失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
//定义异步操作
var promise = new Promise (function (resolve,reject)) {// ... some code if(/* 异步操作成功 */){resolve(value)} else {reject(error)}
}//异步操作的回调(写法一)
promise.then( function( result ) {// result ==上面的valueconsole.log("fulfilled:",val)
}).catch(function (error){// error==上面的errorconsole.log('rejected',err)
});//异步操作的回调(写法二)
promise.then((result) => console.log("fulfilled:",result)).catch((error) =>console.log('rejected',error));
Promise.all()
除了串行执行若干异步任务外,Promise还可以并行执行异步任务。
Promise.all() 可以将多个Promise实例包装成一个新的Promise实例;
const p = Promise.all([p1, p2, p3]);
p
的状态由p1
、p2
、p3
决定,分成两种情况。(1)只有
p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。(2)只要
p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
2、Blob对象和File
对象
Blob对象
Blob对象有一个slice方法,返回一个新的
Blob
对象,包含了源Blob对象中制定范围内的数据。var blob = instanceOfBlob.slice([start [, end [, contentType]]]};
参数说明:
start: 可选,代表 Blob 里的下标,表示第一个会被会被拷贝进新的 Blob 的字节的起始位置。如果传入的是一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。
end: 可选,代表的是 Blob 的一个下标,这个下标-1的对应的字节将会是被拷贝进新的Blob 的最后一个字节。如果你传入了一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。
contentType
可选给新的 Blob 赋予一个新的文档类型。这将会把它的 type 属性设为被传入的值。它的默认值是一个空的字符串。
通过slice方法,从blob1中创建出一个新的blob对象,size等于3。
var data = "abcdef";
var blob1 = new Blob([data]);
var blob2 = blob1.slice(0,3);console.log(blob1); //输出:Blob {size: 6, type: ""}
console.log(blob2); //输出:Blob {size: 3, type: ""}
File继承字Blob,因此我们可以调用slice方法对大文件进行分片上传。
3、FileReader函数
FileReader的使用方式非常简单分为三个步骤:
1.创建FileReader
对象 2.读取文件 3.处理文件读取事件(完成,中断,错误等...)
创建FileReader对象
let reader = new FileReader();
读取文件
FileReader 的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。
上面的表格列出了这些方法以及他们的参数和功能,需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果, 这一结果存储在 result属性中。
方法名 参数 描述 abort 无 中断读取 readAsBinaryString file 将文件读取为二进制码 readAsDataURL file 将文件读取为 DataURL readAsText file, [文件编码] 将文件读取为文本 //1.将文件读取为二进制数据 reader.readAsBinaryString(file); //2.将文件读取为文本数据 reader.readAsText(file,"UTF-8")
读取事件
FileReader
包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。
事件 描述 onabort 中断时触发 onerror 出错时触发 onload 文件读取成功完成时触发 onloadend 读取完成触发,无论成功或失败 onloadstart 读取开始时触发 onprogress 读取中
完整读取示例
//1.获取文件对象let file = data.file;//2.创建FileReader对象,用于读取文件let reader = new FileReader();//3.将文件读取为二进制码reader.readAsBinaryString(file);//4.处理读取事件//4.1读取完成事件,获取数据reader.onload = (e) => {//获取数据const data = e.currentTarget.result;};//4.2 //读取中断事件reader.onabort = () => {console.log('读取中断了');};
4、前端文件转MD5
MD5计算将整个文件或者字符串,通过其不可逆的字符串变换计算,产生文件或字符串的MD5散列值。
因此MD5常用于校验文件,以防止文件被“篡改”。因为如果文件、字符串的MD5散列值不一样,说明文件内容也是不一样的
安装依赖
npm install spark-md5 --save
导包
import SparkMD5 from 'spark-md5'
要配合js的 FileReader 函数来使用 SparkMD5
const getFileMD5 = (file:File) => {return new Promise((resolve, reject) => {const spark = new SparkMD5.ArrayBuffer()const fileReader = new FileReader()fileReader.onload = (e:any) => {spark.append(e.target.result)resolve(spark.end())}fileReader.onerror = () => {reject('')}fileReader.readAsArrayBuffer(file)})
}
6、
Minio基本知识
minio下载启动
minio:对象存储服务。一个对象文件可以是任意大小,从几kb到最大5T不等
中文网站: MinIO | 高性能分布式存储,私有云存储
下载后:新建一个minioData文件夹用来存储上传的文件
在minio.exe文件夹的路径处输入cmd进入命令行界面(该exe文件不能双击运行)
输入命令:minio.exe server E:\server\minio\install\minioData
接着访问:http://localhost:9000/
用户名和密码都是minioadmin
基础概念
Object:存储到minio中的基本对象,如文件、字节流
Bucket:存放文件的顶层目录,起到一个隔离的作用
Drive:存储数据的磁盘
mc客户端使用
MinIO 提供客户端工具访问和操作服务端。MinIO 客户端工具 mc(minio client)
提供了类似 unix 的命令去操作服务端。mc 相关命令列表如下所示(请查看英文官网):
ls 列出文件和文件夹。
mb 创建一个存储桶或一个文件夹。
cat 显示文件和对象内容。
pipe 将一个STDIN重定向到一个对象或者文件或者STDOUT。
share 生成用于共享的URL。
cp 拷贝文件和对象。
mirror 给存储桶和文件夹做镜像。
find 基于参数查找文件。
diff 对两个文件夹或者存储桶比较差异。
rm 删除文件和对象。
events 管理对象通知。
watch 监听文件和对象的事件。
policy 管理访问策略。
session 为cp命令管理保存的会话。
config 管理mc配置文件。
update 检查软件更新。
version 输出版本信息。
查看 minio服务端
mc config host ls
添加服务端
mc config host add xiayumao_minio http://127.0.0.1:9000 minioadmin minioadmin
再次查看
删除服务端
mc config host remove xiayumao_minio
mc config host add minio-server http://127.0.0.1:9000 minioadmin minioadmin
查看
ls命令列出文件、对象和存储桶。
-----------------
创建桶
mc mb minio-server/sringcloud
递归创建桶,对吗?
mc mb minio-server/nacos/2023/9/23
springboot整合minio
依赖和配置
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version></dependency>
application.yml 配置信息
minio:endpoint: http://127.0.0.1:9000 #Minio服务所在地址accessKey: minioadmin #账号secretKey: minioadmin #密码
注入MinioClient
关于 MinIO 的一切操作都得通过 MinioClient
对象来进行
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {private String endpoint;private String accessKey;private String secretKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint)//服务地址.credentials(accessKey, secretKey)//账号 密码.build();}
}
封装minio桶操作
通过MinioClient
对象,指定 Bucket 即可进行相应的操作。
@Component
@Slf4j
public class MinioUtil {@Resourceprivate MinioClient minioClient;/*** 查看存储bucket是否存在** @return boolean*/public Boolean bucketExists(String bucketName) {Boolean found;try {found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return found;}/*** 创建存储bucket** @return Boolean*/public Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 删除存储bucket** @return Boolean*/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 获取全部bucket*/public List<Bucket> getAllBuckets() {try {List<Bucket> buckets = minioClient.listBuckets();return buckets;} catch (Exception e) {e.printStackTrace();}return null;}
}
桶操作接口测试
@Slf4j
@RestController
@RequestMapping(value = "product/file")
public class FileController {@Autowiredprivate MinioUtil minioUtil;@Autowiredprivate MinioConfig prop;//查看存储bucket是否存在@GetMapping("/bucketExists")public Boolean bucketExists(@RequestParam("bucketName") String bucketName) {return minioUtil.bucketExists(bucketName);}//创建存储bucket@GetMapping("/makeBucket")public Boolean makeBucket(String bucketName) {return minioUtil.makeBucket(bucketName);}//删除存储bucket@GetMapping("/removeBucket")public Boolean removeBucket(String bucketName) {return minioUtil.removeBucket(bucketName);}//获取全部bucket@GetMapping("/getAllBuckets")public List getAllBuckets() {return minioUtil.getAllBuckets();}
}