首页 前端知识 vue项目,使用js Minio实现文件的上传和下载

vue项目,使用js Minio实现文件的上传和下载

2024-06-10 23:06:58 前端知识 前端哥 639 845 我要收藏

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>

转载请注明出处或者链接地址:https://www.qianduange.cn//article/11805.html
标签
评论
发布的文章

第一次实验补充

2024-06-18 09:06:14

html5shiv,从入门到深入

2024-05-09 10:05:07

html5基础入门

2024-06-18 09:06:07

HTML5学习简记

2024-06-18 09:06:20

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!