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

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


    我们可在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
        }
    }
    




     
### 公网文件上传、下载、分享与存储的技术分析 #### 技术概述 在现代互联网应用中,公网文件上传、下载、分享以及存储是一项核心功能。无论是企业级应用还是个人项目,都需要依赖稳定高效的解决方案来满足这些需求。以下是关于这一主题的关键技术和方法。 --- #### .NET 平台下的批量大文件处理 .NET 生态提供了多种框架和技术用于实现文件的高效传输和管理。例如,在 ASP.NET MVC 或者 .NET Core 中,开发者可以通过 HTTP 协议设计接口以支持大文件的分片上传和断点续传[^1]。这种机制能够显著提升用户体验并降低网络波动带来的影响。 对于实际开发而言,通常会采用如下策略: - **前端切片**:将大文件分割成多个小片段逐一发送至服务器端。 - **后端重组**:接收各部分数据包后再拼接还原原始文件结构。 下面是一个简单的 C# 实现示例: ```csharp public async Task<IActionResult> UploadFile(IFormFile fileChunk, int chunkIndex, string fileName) { var filePath = Path.Combine("Uploads", fileName); using (var stream = new FileStream(filePath, FileMode.Append)) { await fileChunk.CopyToAsync(stream); } return Ok(); } ``` 此代码展示了如何逐块保存客户端传递过来的数据流,并最终形成完整的文档实体。 --- #### 应用场景举例 除了传统的业务流程外,还有许多日常操作涉及到了类似的逻辑。比如当人们利用邮件服务附加资料或者借助办公自动化(OA)平台递交报告材料的时候都会运用到相应的算法模型[^2];另外像社交媒体允许用户修改自己的虚拟形象照片也是基于相似原理构建起来的服务体系之一。 --- #### 跨设备间的大规模资源转移方案探讨 针对不同环境下的具体条件差异性较大情况,则需考虑更为灵活多样的途径来进行跨地域间的资源共享活动。如果目标机器处于局域内部署状态的话可以直接选用FTP协议作为主要通讯手段完成整个过程中的各项事务处理工作;而一旦涉及到外部访问请求就需要额外配置防火墙规则开放特定端口权限以便于正常通信连接建立成功之后再继续后续动作执行下去直至结束为止[^3]。 另一种流行的选择是部署私有化的对象储存系统——MinIO 。它不仅具备良好的扩展性和兼容性特点而且还能很好地适配现有的CI/CD流水线作业模式从而进一步简化运维管理工作负担程度的同时也提高了整体系统的可靠性和安全性水平层次上的表现效果明显优于传统方式很多倍数以上不等具体情况视乎实际应用场景的需求范围大小有所不同而已[^4]。 --- ### 总结 综上所述可以看出围绕着公共网络环境下开展的各种形式各异但目的相同的任务背后隐藏着极其复杂的科学技术含量在里面值得深入研究学习掌握其中蕴含的知识要点才能更好地服务于社会大众群体利益最大化原则之上不断探索前进方向努力成为新时代信息化建设浪潮当中不可或缺的重要力量源泉所在之处发光发热贡献自己的一份绵薄之力吧! ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值