1 启动minio

.\minio.exe server D:\CodeNext\miniojs\minioFolder

2 创建client

import * as Minio from 'minio'

const minioClient = new Minio.Client({
  endPoint: 'localhost',
  port: 9000,
  useSSL: false,
  accessKey: 'minioadmin',
  secretKey: 'minioadmin',
})

3 Bucket-用例1 bucket操作 创建-list-是否存在-移除


minioClient.makeBucket('mybucket', function (err) {
    if (err) return console.log('Error creating bucket with object lock.', err)
    console.log('Bucket created successfully in "us-east-1" and enabled object lock')
  })


 try {
    const buckets = await minioClient.listBuckets()
    console.log('Success', buckets)
  } catch (err) {
    console.log(err.message)
  }

const exists = await minioClient.bucketExists('mybucket')
if (exists) {
  console.log('Bucket exists.')
}

try {
    await minioClient.removeBucket('mybucket')
    console.log('Bucket removed successfully.')
  } catch (err) {
    console.log('unable to remove bucket.')
  }

4 Bucket-用例2 新建bucket-上传文件及文件夹-查看

minioClient.makeBucket('mybucket', function (err) {
    if (err) return console.log('Error creating bucket with object lock.', err)
    console.log('Bucket created successfully in "us-east-1" and enabled object lock')
  })


  const data = []
  const stream = minioClient.listObjects('mybucket', '', true)
  stream.on('data', function (obj) {
    data.push(obj)
  })
  stream.on('end', function () {
    console.log(data)
  })
  stream.on('error', function (err) {
    console.log(err)
  })

打印


[
  {
    name: 'A_Penthouse.dgn',
    lastModified: 2024-10-29T06:14:03.557Z,
    etag: 'ebbe65a1e3e090c30a402ada444a1127',
    size: 5001216
  },
  {
    name: 'Design1/Design.dgn',
    lastModified: 2024-10-29T06:14:13.429Z,
    etag: '916d544b4ec16761ebab1fc638b61e80',
    size: 8399872
  }
]

5 Bucket-用例3 给Bucket打version

const versioningConfig = { Status: 'Enabled' }
await minioClient.setBucketVersioning('mybucket', versioningConfig)

const versionInfo = await minioClient.getBucketVersioning('mybucket')
console.log('Success ', versionInfo)

6 Bucket Policy

const readPolicy = {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::**",
        }
    ]
}

await minioClient.setBucketPolicy('mybucket',JSON.stringify(readPolicy) );
const policyDetail = await minioClient.getBucketPolicy('mybucket')

console.log(`Bucket policy file: ${policyDetail}`)

结果

这里的policy这里会有一些概念是来自amazon,arn是资源,IAM代表身份和访问管理(Identity and Access Management)

7 Object 上传

putObject

const file = './tmp/test.json'
const fileStream = Fs.createReadStream(file)
const fileStat = Fs.stat(file, function (err, stats) {
  if (err) {
    return console.log(err)
  }
  minioClient.putObject('mybucket', 'test.json', fileStream, stats.size, function (err, objInfo) {
    if (err) {
      return console.log(err) // err should be null
    }
    console.log('Success', objInfo)
  })
})
fileStat;

fputObject

FPutObject,把指定文件上传到一个对象中。当对象小于 128MB 时,会调用一次 PUT 请求进行上传。当大于 128MB 时,会根据文件的实际大小自动拆分成 128MB 一块或更大一些的块儿进行分片上传。需要注意是对象的最大大小是 5TB。

const file = './tmp/big.bim'
const metaData = {
  'Content-Type': 'text/html',
  'Content-Language': 123,
  'X-Amz-Meta-Testing': 1234,
  example: 5678,
}
minioClient.fPutObject('mybucket', 'big.bim', file, metaData, function (err, objInfo) {
  if (err) {
    return console.log(err)
  }
  console.log('Success', objInfo.etag, objInfo.versionId)
})

这里上传了一个很大的文件big.bim

运行上传后马上停掉进程,然后去调用listIncompleteUploads去查询,能看到结果

但是注意,实际上,这两种都不能作为前端的直接调用。。而且前端为了安全也不能有client。。后面的预操作可解决
参考文章:预签名

presignedPutObject

const presignedUrl = await minioClient.presignedPutObject('mybucket', 'hello.txt')
console.log(presignedUrl)

用这个地址postman尝试发送hello.txt,可以看到可以成功

前端这里可以去监控这个请求,并记录进度

这里如果要模仿minio做的界面,上传到一部分用户取消,可以发送cancel,参考文章:

cancelToken

下载

listIncompleteUploads

const Stream = minioClient.listIncompleteUploads('mybucket', 'big.bim', true)
  console.log(Stream)
Stream.on('data', function (obj) {
  console.log(obj)
})
Stream.on('end', function () {
  console.log('End')
})
Stream.on('error', function (err) {
  console.log(err)
})

removeIncompleteUpload

删除  await minioClient.removeIncompleteUpload('mybucket', 'big.bim')

8 Object下载

getObject

Downloads an object as a stream 流式下载

fGetObject

minioClient.fGetObject('mybucket', 'A_Penthouse.dgn', './tmp/A_Penthouse.dgn', function (err) {
  if (err) {
    return console.log(err)
  }
  console.log('success')
})

下载文件并将文件保存到本地文件系统。

presignedGetObject

下载(可提供前端)

const presignedUrl = await minioClient.presignedGetObject('mybucket', 'hello.txt', 24 * 60 * 60)
console.log(presignedUrl)

9 Object删除

removeObject

删除单个文件

;(async function () {
  try {
    await minioClient.removeObject('mybucket', 'test.json')
    console.log('Removed the object')
  } catch (err) {
    console.log('Unable to remove object', err)
  }
})()

removeObjects

删除所有文件

const objectsList = []
const objectsStream = minioClient.listObjects('mybucket', '', true)

objectsStream.on('data', function (obj) {
  objectsList.push(obj.name)
})

objectsStream.on('error', function (e) {
  console.log(e)
})

objectsStream.on('end', async () => {
  await minioClient.removeObjects('mybucket', objectsList)
})

这里删除了所有的文件,但是文件夹保留了

删除文件夹

forceDelete: true, 增加删除的Opt可以删除

;(async function () {
  try {
    await minioClient.removeObject('mybucket', 'copy/',{
      forceDelete: true,
    })
    console.log('Removed the object')
  } catch (err) {
    console.log('Unable to remove object', err)
  }
})()

10 Copy 

注意前面是targetBucketName,后面组合的才是sourceBucketNameAndObjectName

 await minioClient.copyObject('mybucket', 'testcopy.json', '/mybucket/test.json')

Condition的解释

例如:只有在指定时间后的才复制

const conds = new Minio.CopyConditions()
//例如仅在源对象最后修改时间在指定时间之后时才复制 2024年11月1日12点0分0秒
conds.setModified(new Date(2024,10,1,12,0,0))
 await minioClient.copyObject('test', 'Design1/hello.txt', '/test/hello.txt',conds)

官网给出来的例子中使用到的setMatchETag,意思应该是和对象的etag符合才copy,对象的 ETag 是一个用于标识对象内容的字符串。对于单个文件上传,ETag 通常是文件内容的 MD5 校验和的十六进制表示。对于分片上传,ETag 是由各个分片的 MD5 校验和组合而成的。MinIO 并没有直接提供设置对象 ETag 的 API

11 消息机制

可以和RabbitQ一起,如文件的删除和新增可以记录

24年最新的minio已经没有config.json了只有文件夹,不要再找了。。。

给某个Bucket设置订阅,然后上传文件,可以看到rabbitQ中有变化

可以看到minio-event 有变化

node处理

// const amqp = require('amqplib/callback_api');
import * as amqp from 'amqplib/callback_api.js'

// 连接到RabbitMQ服务器
amqp.connect('amqp://guest:guest@localhost:5672', (err, conn) => {
  if (err) {
    console.log(err)
    throw err;
  }
  conn.createChannel((err, ch) => {
    if (err) {
      console.log(err)
      throw err;
    }
    const ex = 'minio-events'; // 交换机名称,与MinIO配置中的名称相同

    // 声明一个队列,用于接收消息
    ch.assertExchange(ex, 'direct', { durable: false });
    ch.assertQueue('', { exclusive: true }, (err, q) => {
      if (err) {
        throw err;
      }
      console.log(` [*] Waiting for messages in queue ${q.queue}. To exit press CTRL+C`);

      // 绑定队列到交换机
      ch.bindQueue(q.queue, ex, '');
      ch.consume(q.queue, (msg) => {
        if (msg !== null) {
          console.log(` [x] Received ${msg.content.toString()}`);
          // 在这里处理消息
        }
      }, { noAck: true });
    });
  });
});

bucket做一些操作,如删除,可以看到这些消息

一些有用的链接

minio介绍

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐