MinIO之C#上传文件等各项操作

1,401 阅读4分钟

  1. C# MinIO的SDK
    这里我们使用的是C#的minio.dll,可在nuget中搜索(www.nuget.org/packages?q=…

    我们可在VS的程序包管理器控制台中输入:Install-Package Minio -Version 3.1.13即可获得minio.dll以及其依赖的组件

  2. Demo功能演示
    这里我们主要创建了一个WinForm窗体程序来做演示,主要实现了以下功能:

    批量上传文件到MinIO的桶中
    创建桶/设置访问策略
    获取桶的访问策略
    删除桶
    删除桶文件
    ​​​​​​​ 获取桶文件

    具体窗体界面以及MinIO服务器效果如下图所示:

  3. Demo源码
    具体展示界面对应的后台代码如下所示:

    /*****************************************************************************************************
     * 本代码版权归Quber所有,All Rights Reserved (C) 2021-2088
     * 联系人邮箱:qubernet@163.com
     *****************************************************************************************************
     * 命名空间:Quber.MinIO
     * 类名称:FrmMain
     * 创建时间:2021/2/24 11:38:04
     * 创建人:Quber
     * 创建说明:
     *****************************************************************************************************
     * 修改人:
     * 修改时间:
     * 修改说明:
    *****************************************************************************************************/
    using Minio;
    using Minio.DataModel;
    using Minio.Exceptions;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Quber.MinIO
    {
        /// <summary>
        /// 
        /// </summary>
        public partial class FrmMain : Form
        {
            /// <summary>
            /// 定义MinIO客户端对象
            /// </summary>
            private MinioClient minio;
    
            public FrmMain()
            {
                InitializeComponent();
    
                minio = new MinioClient("192.168.3.200:9000", "minioadmin", "minioadmin");
            }
    
            #region 上传文件
    
            /// <summary>
            /// 浏览文件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnSelect_Click(object sender, EventArgs e)
            {
                if (fdMain.ShowDialog() == DialogResult.OK)
                {
                    txtSelect.Text = string.Join(",", fdMain.FileNames);
    
                    lblCount.Text = "共选择" + fdMain.FileNames.Length + "个文件!";
                }
            }
    
            /// <summary>
            /// 开始上传
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void btnUpload_Click(object sender, EventArgs e)
            {
                var bucketName = txtBucketNameUpload.Text.Trim();
                if (string.IsNullOrWhiteSpace(bucketName))
                {
                    MessageBox.Show("请输入桶名称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtBucketNameUpload.Focus();
                    return;
                }
                if (fdMain.FileNames.Length == 0)
                {
                    MessageBox.Show("请选择要上传的文件!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
    
                txtBucketNameUpload.Enabled = false;
                btnUpload.Enabled = false;
                btnSelect.Enabled = false;
    
                try
                {
                    for (int i = 0; i < fdMain.FileNames.Length; i++)
                    {
                        lblMsg.Text = "正在上传第" + (i + 1) + "个文件!";
    
                        var ret = await UploadFile(minio, bucketName, fdMain.FileNames[i]);
                        lblMsg.Text = "第" + (i + 1) + "个文件" + ret;
    
                        await Task.Run(() => { Thread.Sleep(2000); });
    
                        if (i == fdMain.FileNames.Length - 1)
                        {
                            lblMsg.Text = "所选的" + fdMain.FileNames.Length + "个文件全部上传完成!";
                            await Task.Run(() => { Thread.Sleep(2000); });
                            lblMsg.Text = "--";
                        }
                    }
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.Message;
                }
    
                txtBucketNameUpload.Enabled = true;
                btnUpload.Enabled = true;
                btnSelect.Enabled = true;
                txtSelect.Text = "";
            }
    
            /// <summary>
            /// 上传文件到MinIO
            /// </summary>
            /// <param name="minio"></param>
            /// <param name="bucketName"></param>
            /// <param name="filePath"></param>
            /// <returns></returns>
            private async Task<string> UploadFile(MinioClient minio, string bucketName, string filePath)
            {
                return await Task.Run(async () =>
                {
                    var retMsg = string.Empty;
    
                    try
                    {
                        //上传到MinIO中的文件名称
                        var objName = filePath.Substring(filePath.LastIndexOf('\\') + 1, filePath.Length - filePath.LastIndexOf('\\') - 1);
    
                        //检查是否存在桶
                        bool existBucket = await minio.BucketExistsAsync(bucketName);
                        if (!existBucket)
                        {
                            //创建桶
                            await minio.MakeBucketAsync(bucketName);
    
                            //设置桶的访问权限(读、写、读和写)
                            await SetPolicyAsync(bucketName, 1);
                        }
    
                        //上传文件到桶中
                        await minio.PutObjectAsync(bucketName, objName, filePath);
    
                        retMsg = "成功上传:" + objName;
                    }
                    catch (MinioException e)
                    {
                        retMsg = "文件上传错误:" + e.Message;
                    }
    
                    return retMsg;
                });
            }
    
            #endregion
    
            #region 创建桶/设置访问策略
    
            /// <summary>
            /// 设置
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void btnBucket_Click(object sender, EventArgs e)
            {
                var bucketName = txtBucketName.Text.Trim();
                if (string.IsNullOrWhiteSpace(bucketName))
                {
                    MessageBox.Show("请输入桶名称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtBucketName.Focus();
                    return;
                }
    
                //检查是否存在桶
                bool existBucket = await minio.BucketExistsAsync(bucketName);
                if (!existBucket)
                {
                    //创建桶
                    await minio.MakeBucketAsync(bucketName);
                }
    
                var policyType = rbRead.Checked ? 1 :
                rbWrite.Checked ? 2 : 3;
    
                await SetPolicyAsync(bucketName, policyType);
    
                MessageBox.Show("桶名称" + bucketName + "设置成功!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
    
            #endregion
    
            #region 获取桶访问策略
    
            /// <summary>
            /// 获取策略
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void btnGetPolicy_Click(object sender, EventArgs e)
            {
                var bucketName = txtGetPolicy.Text.Trim();
                if (string.IsNullOrWhiteSpace(bucketName))
                {
                    MessageBox.Show("请输入桶名称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtGetPolicy.Focus();
                    return;
                }
    
                //检查是否存在桶
                bool existBucket = await minio.BucketExistsAsync(bucketName);
                if (existBucket)
                {
                    txtGetPolicyInfo.Text = await minio.GetPolicyAsync(bucketName);
                }
                else
                {
                    MessageBox.Show("桶名称" + bucketName + "不存在!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            #endregion
    
            #region 删除桶
    
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void btnDeleteBucket_Click(object sender, EventArgs e)
            {
                var bucketName = txtDeleteBucket.Text.Trim();
                if (string.IsNullOrWhiteSpace(bucketName))
                {
                    MessageBox.Show("请输入桶名称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtDeleteBucket.Focus();
                    return;
                }
    
                try
                {
                    //检查是否存在桶
                    bool existBucket = await minio.BucketExistsAsync(bucketName);
                    if (existBucket)
                    {
                        if (MessageBox.Show("确认要删除桶" + bucketName + "?", "此删除不可恢复", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            await minio.RemoveBucketAsync(bucketName);
                            MessageBox.Show("桶名称" + bucketName + "删除成功!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                    else
                    {
                        MessageBox.Show("桶名称" + bucketName + "不存在!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("桶名称" + bucketName + "删除异常:" + ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            #endregion
    
            #region 删除桶文件
    
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void btnDeleteFile_Click(object sender, EventArgs e)
            {
                string bucketName = txtDeleteFileBucket.Text.Trim(),
                    fileName = txtDeleteFileName.Text.Trim();
                if (string.IsNullOrWhiteSpace(bucketName))
                {
                    MessageBox.Show("请输入桶名称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtDeleteFileBucket.Focus();
                    return;
                }
                if (string.IsNullOrWhiteSpace(fileName))
                {
                    MessageBox.Show("请输入文件名!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtDeleteFileName.Focus();
                    return;
                }
    
                try
                {
                    //检查是否存在桶
                    bool existBucket = await minio.BucketExistsAsync(bucketName);
                    if (existBucket)
                    {
                        if (MessageBox.Show("确认要删除" + fileName + "?", "此删除不可恢复", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            await minio.RemoveObjectAsync(bucketName, fileName);
                            MessageBox.Show("文件" + fileName + "删除成功!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                    else
                    {
                        MessageBox.Show("桶名称" + bucketName + "不存在!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("桶名称" + bucketName + "删除异常:" + ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            #endregion
    
            #region 获取桶文件
    
            /// <summary>
            /// 获取
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void btnGetBucketFiles_Click(object sender, EventArgs e)
            {
                var bucketName = txtGetBucketFiles.Text.Trim();
                if (string.IsNullOrWhiteSpace(bucketName))
                {
                    MessageBox.Show("请输入桶名称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtGetBucketFiles.Focus();
                    return;
                }
    
                txtGetBucketFilesInfo.Text = "";
    
                //检查是否存在桶
                bool existBucket = await minio.BucketExistsAsync(bucketName);
                if (existBucket)
                {
                    //获取到的文件集合
                    var fileList = new List<string>();
    
                    var observable = minio.ListObjectsAsync(bucketName);
                    observable.Subscribe(item =>
                    {
                        fileList.Add(item.Key);
                    }, ex =>
                    {
                    }, () =>
                    {
                        txtGetBucketFilesInfo.Text = string.Join("\r\n", fileList);
                    });
                }
                else
                {
                    MessageBox.Show("桶名称" + bucketName + "不存在!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            #endregion
    
            #region 公用方法
    
            /// <summary>
            /// 设置桶的访问策略(读、写、读和写)
            /// </summary>
            /// <param name="bucketName"></param>
            /// <param name="policyType"></param>
            /// <returns></returns>
            private async Task SetPolicyAsync(string bucketName, int policyType = 1)
            {
                //设置桶的访问权限(读、写、读和写)
                var policyRead = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME\"],\"Condition\":{\"StringEquals\":{\"s3:prefix\":[\"BUCKETPREFIX\"]}}},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME/BUCKETPREFIX*\"]}]}";
                var policyWrite = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME/BUCKETPREFIX*\"]}]}";
                var policyReadWrite = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME\"],\"Condition\":{\"StringEquals\":{\"s3:prefix\":[\"BUCKETPREFIX\"]}}},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\"],\"Resource\":[\"arn:aws:s3:::BUCKETNAME/BUCKETPREFIX*\"]}]}";
    
                var policySet = policyType == 1 ? policyRead :
                   policyType == 2 ? policyWrite : policyReadWrite;
    
                await minio.SetPolicyAsync(bucketName, policySet.Replace("BUCKETNAME", bucketName).Replace("BUCKETPREFIX", "*.*"));
            }
    
            #endregion
        }
    }