1 什么是MinIO
MinlO是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据。例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。MinlO是一个非常轻量的服务 可以很简单的和其他应用的结合,类似NodeJS, Redis或者MySQL。
- 社区地址 - https://slack.min.io
- 文档地址(文档推荐)- https://docs.min.io
- 中文文档-http://docs.minio.org.cn/docs/
- 官网地址- https://min.io
2 使用MinIO实现上传和下载
2.1 安装相关依赖
npm install minio --save
npm install stream --save
2.2 连接minIO服务
参考文档
let Minio = require('minio')
let stream = require('stream')
//连接minio文件服务器
var minioClient = new Minio.Client({
endPoint: '', //对象存储服务的URL
port: 9000, //端口号
useSSL: false, //true代表使用HTTPS
accessKey: '', //账户id
secretKey: '', //密码
});
3 示例代码
主要实现功能
- 用户选择文件夹,将文件夹下文件进行上传
- 用户可以通过浏览器下载指定文件
<template>
<div style="margin:5px 5px">
<el-button @click="getFileName" type="primary">选择文件</el-button>
<input type="file" webkitdirectory multiple="multiple" id="minIoFile" ref="minIoFile" v-show="false" @change="getFile">
<el-button v-if="fileList.length>0" type="primary" @click="upload">上传</el-button>
<el-button type="primary" @click="download">下载</el-button>
</div>
</template>
<script>
let Minio = require('minio')
let stream = require('stream')
//连接minio文件服务器
var minioClient = new Minio.Client({
endPoint: '', //对象存储服务的URL
port: 9000, //端口号
useSSL: false, //true代表使用HTTPS
accessKey: '', //账户id
secretKey: '', //密码
});
export default {
name: 'MesAdivce',
data: () => ({
fileList: [],
}),
methods: {
download(filename, names) {
minioClient.bucketExists('ecgdata', async function(err) {
if (err) {
if (err.code == 'NoSuchBucket') return console.log("bucket does not exist.")
return console.log(err)
}
//存在
const file = await new Promise((resolve, reject)=>{
minioClient.getObject('ecgdata', '4A3D8BF371C044FDB3CED70010801EF5/1.3.12.2.1107.5.6.1.2387.30200122071903025612700000098.DCM', function (err, dataStream) {
let size = 0;
let file = [];
dataStream.on('data', function (chunk) {
size += chunk.length
console.log(chunk);
let aaa = Array.from(chunk)
file = file.concat(aaa);
})
dataStream.on('end', function () {
resolve(file)
})
dataStream.on('error', function (err) {
resolve(false)
})
})
})
// 进行下载
const blob = new Blob([file])
const blobUrl = URL.createObjectURL(blob)
const a = document.createElement('a')
a.setAttribute('href', blobUrl)
a.setAttribute('download', '1.3.12.2.1107.5.6.1.2387.30200122071903025612700000098.DCM')
a.click()
})
},
upload() {
this.fileList.map((item, index) => {
this.uploadMinIo(item, index);
})
},
getFileName() {
let inputDOM = this.$refs.minIoFile;
inputDOM.click();
},
getFile(event) {
let files = document.getElementById('minIoFile').files;
let arr = [];
let fileSwitch = true;
if (files.length > 0) {
for (let i = 0; i < files.length; i++) {
if ((files[i].size / 1024 / 1024).toFixed(5) > 64) {
this.$message({
message: `${item.name}超过文件的最大长度`,
type: 'warning'
});
fileSwitch = false;
}
}
if (fileSwitch) {
for (let i = 0; i < files.length; i++) {
if ((files[i].type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') ||
(files[i].type == 'application/vnd.ms-excel') ||
(files[i].type == 'text/plain') ||
(files[i].type == 'image/png') ||
(files[i].type == 'image/gif') ||
(files[i].type == 'image/jpg') ||
(files[i].type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') ||
(files[i].type == 'application/vnd.openxmlformats-officedocument.presentationml.presentation')
) {
this.fileList.push(files[i])
} else {
console.log("类型不对");
}
}
}
}
},
//上传文件
uploadMinIo(fileObj, index) {
this.fileList = this.fileList.filter((self, el) => {
return self != fileObj
})
let vm = this
// const files = fileObj;
if (fileObj) {
let file = fileObj
//获取文件类型及大小
const fileName = file.webkitRelativePath
const mineType = file.type
const fileSize = file.size
//参数
let metadata = {
"content-type": mineType,
"content-length": fileSize
}
//判断储存桶是否存在
minioClient.bucketExists('ecgdata', function(err) {
if (err) {
if (err.code == 'NoSuchBucket') return console.log("bucket does not exist.")
return console.log(err)
}
//准备上传
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function(e) { //读取完成触发,无论成功或失败
const dataurl = e.target.result
//base64转blob
const blob = vm.toBlob(dataurl)
//blob转arrayBuffer
let reader2 = new FileReader()
reader2.readAsArrayBuffer(blob)
reader2.onload = function(ex) {
//定义流
let bufferStream = new stream.PassThrough();
//将buffer写入
bufferStream.end(new Buffer(ex.target.result));
//上传
minioClient.putObject('ecgdata', fileName, bufferStream, fileSize, metadata, function(err,
etag) {
console.log(etag);
})
}
}
})
}
},
//base64转blob
toBlob(base64Data) {
let byteString = base64Data
if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1]) // base64 解码
} else {
byteString = unescape(base64Data.split(',')[1])
}
// 获取文件类型
let mimeString = base64Data.split(';')[0].split(":")[1] // mime类型
// ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
// let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
// let uintArr = new Uint8Array(arrayBuffer) // 创建视图
let uintArr = new Uint8Array(byteString.length) // 创建视图
for (let i = 0; i < byteString.length; i++) {
uintArr[i] = byteString.charCodeAt(i)
}
// 生成blob
const blob = new Blob([uintArr], {
type: mimeString
})
// 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
return blob
},
},
}
</script>