MinIO (五) .net core实现分片上传

news/2024/5/20 0:28:33 标签: .netcore

开发环境

Win11

vs2022

appsettings.json添加配置项

  //minIO配置
  "MinIO": {
    //服务器IP
    "Endpoint": "192.168.xx.xx:9090",
    //账号
    "AccessKey": "3xR7i4zs1vLnxxxxxxxx",
    //密码
    "SecretKey": "P6bAnyzJm47Ub4WsIaz3TB4MCxbF5Bk2xxxxxxxx",
    //默认存储桶
    "Bucket": "demo",
    //保存文件的根目录
    "BucketDirectory": "c:\\aaa\\bbb\\ccc",
    //服务的URL地址
    "ServiceURL": "http://192.168.xx.xx:9090" //不可以用localhost,要用IP,比服务器IP多了一个http前缀
  }

注入代码

[ApiController]
[Route("api/[controller]/[action]")]
//[Authorize]
public class MinIOController : ControllerBase
{
    private static string _bucketName = string.Empty;//默认桶
    private static string _accessKey = string.Empty;
    private static string _secretKey = string.Empty;
    private readonly MinioClient _client;
    private readonly IConfiguration _configuration;
    private readonly IHttpClientFactory _httpClient;

    public MinIOController(MinioClient client,
        IConfiguration configuration,
        IHttpClientFactory httpClient)
    {
        _client = client;
        _configuration = configuration;
        _accessKey = configuration["MinIO:AccessKey"];
        _secretKey = configuration["MinIO:SecretKey"];
        _bucketName = configuration["MinIO:Bucket"];
        _httpClient = httpClient;
    }
    
    //。。。。。。

}

接下来是后端进行分片上传的代码示例,有两个,第一个是从官方考下来的代码示例,第二个是自己整理后的代码示例。

从官方考下来的代码示例

#region 后端进行分片上传示例(从官方文档上考下来的)
/// <summary>
/// 后端进行分片上传示例(从官方文档上考下来的)
/// </summary>
/// <param name="formFile">文件流</param>
/// <returns></returns>
[HttpPost]
public virtual async Task<IActionResult> UploadPartAsync(IFormFile formFile)
{
    AmazonS3Config config = new AmazonS3Config()
    {
        ServiceURL = _configuration["MinIO:ServiceURL"]  //"http://192.168.50.36:9090/",
        //ServiceURL = "https://folder.s3.amazonaws.com/",
        //RegionEndpoint = Amazon.RegionEndpoint.CNNorth1
    };

    int MB = (int)Math.Pow(2, 20);  //以兆(M)为单位

    // Create a client
    using AmazonS3Client amazonS3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);

    // Define input stream
    Stream inputStream = formFile.OpenReadStream(); //Create13MBDataStream();

    // Initiate multipart upload
    InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest
    {
        BucketName = "test",
        Key = "Item1"
    };
    //InitiateMultipartUploadResponse initResponse = client.InitiateMultipartUpload(initRequest);
    InitiateMultipartUploadResponse initResponse = await amazonS3Client.InitiateMultipartUploadAsync(initRequest);

    GetPreSignedUrlRequest urlRequest = new GetPreSignedUrlRequest()
    {
        BucketName = "test",
        Key = "Item1",
        PartNumber = 1,
        Expires = DateTime.Now.AddMinutes(1)
    };

    // Upload part 1
    UploadPartRequest uploadRequest = new UploadPartRequest
    {
        BucketName = "test",
        Key = "Item1",
        UploadId = initResponse.UploadId,
        PartNumber = 1,
        PartSize = 6 * MB,
        InputStream = inputStream
    };
    UploadPartResponse up1Response = await amazonS3Client.UploadPartAsync(uploadRequest);

    // Upload part 2
    uploadRequest = new UploadPartRequest
    {
        BucketName = "test",
        Key = "Item1",
        UploadId = initResponse.UploadId,
        PartNumber = 2,
        PartSize = 6 * MB,
        InputStream = inputStream
    };
    UploadPartResponse up2Response = await amazonS3Client.UploadPartAsync(uploadRequest);

    // Upload part 3
    uploadRequest = new UploadPartRequest
    {
        BucketName = "test",
        Key = "Item1",
        UploadId = initResponse.UploadId,
        PartNumber = 3,
        InputStream = inputStream
    };
    UploadPartResponse up3Response = await amazonS3Client.UploadPartAsync(uploadRequest);

    // List parts for current upload
    ListPartsRequest listPartRequest = new ListPartsRequest
    {
        BucketName = "test",
        Key = "Item1",
        UploadId = initResponse.UploadId
    };
    ListPartsResponse listPartResponse = await amazonS3Client.ListPartsAsync(listPartRequest);
    Debug.Assert(listPartResponse.Parts.Count == 3);

    // Complete the multipart upload  分片上传完后合并
    CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest
    {
        BucketName = "test",
        Key = "Item1",
        UploadId = initResponse.UploadId,
        PartETags = new List<PartETag>
        {
            new PartETag { ETag = up1Response.ETag, PartNumber = 1 },  //ETag就是分片信息
            new PartETag { ETag = up2Response.ETag, PartNumber = 2 },
            new PartETag { ETag = up3Response.ETag, PartNumber = 3 }
        }
    };
    CompleteMultipartUploadResponse compResponse = await amazonS3Client.CompleteMultipartUploadAsync(compRequest);

    return Ok();
}
#endregion 后端进行分片上传示例

整理后的后端进行分片上传

#region 后端进行分片上传示例
/// <summary>
/// 后端进行分片上传示例
/// </summary>
/// <param name="path">要上传的文件路径</param>
/// <param name="key">上传到MinIO的路径</param>
/// <returns></returns>
[HttpPost]
public virtual async Task<IActionResult> UploadPartTestAsync(string path, string key)
{
    try
    {
        AmazonS3Config config = new AmazonS3Config()
        {
            ServiceURL = _configuration["MinIO:ServiceURL"]  //"http://192.168.50.36:9090/",
            //ServiceURL = "https://folder.s3.amazonaws.com/",
            //RegionEndpoint = Amazon.RegionEndpoint.CNNorth1
        };

        int MB = (int)Math.Pow(2, 20);  //以兆(M)为单位(等同于1*1024*1024)
        List<PartETag> partETagList = new List<PartETag>();
        int partSize = 30 * MB;  //每片大小

        // Create a client
        using AmazonS3Client amazonS3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);

        Stopwatch sw = new Stopwatch();
        sw.Start();
        //文件流
        //Stream inputStream = formFile.OpenReadStream(); //Create13MBDataStream();
        //var files = Request.Form.Files;
        using Stream inputStream = new FileStream(path, FileMode.OpenOrCreate);
        //await files[0].CopyToAsync(inputStream);

        // Initiate multipart upload
        InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest
        {
            BucketName = _configuration["MinIO:Bucket"],
            Key = key
        };
        //初始化分片上传,得到UploadId
        //InitiateMultipartUploadResponse initResponse = client.InitiateMultipartUpload(initRequest);
        InitiateMultipartUploadResponse initResponse = await amazonS3Client.InitiateMultipartUploadAsync(initRequest);
        TimeSpan ts = sw.Elapsed;
        sw.Restart();

        //得到URL
        //GetPreSignedUrlRequest urlRequest = new GetPreSignedUrlRequest()
        //{
        //    BucketName = _configuration["MinIO:Bucket"],
        //    Key = key,
        //    PartNumber = 1,
        //    Expires = DateTime.Now.AddMinutes(1)
        //};

        //分片数
        //int partCount = (int)Math.Ceiling((decimal)formFile.Length / partSize);
        int partCount = (int)Math.Ceiling((decimal)inputStream.Length / partSize);
        var tasks = new List<Task<UploadPartResponse>>();
        for (int i = 1; i <= partCount; i++)
        {
            UploadPartRequest uploadRequest = new UploadPartRequest();
            uploadRequest.BucketName = _configuration["MinIO:Bucket"];
            uploadRequest.Key = key;
            uploadRequest.UploadId = initResponse.UploadId;
            uploadRequest.PartNumber = i;
            uploadRequest.InputStream = inputStream;
            if (i != partCount)
            {
                uploadRequest.PartSize = partSize;
            }
            //进行分片上传
            UploadPartResponse up1Response = await amazonS3Client.UploadPartAsync(uploadRequest);
            //tasks.Add(Task.Run(async () => await amazonS3Client.UploadPartAsync(uploadRequest)));
            PartETag partETag = new PartETag { ETag = up1Response.ETag, PartNumber = i };
            partETagList.Add(partETag);
        }
        //UploadPartResponse[] resultArr = await Task.WhenAll(tasks.ToArray());
        //for (int i = 0; i < resultArr.Length; i++)
        //{
        //    PartETag partETag = new PartETag { ETag = resultArr[i].ETag, PartNumber = i };
        //    partETagList.Add(partETag);
        //}
        TimeSpan ts2 = sw.Elapsed;
        sw.Restart();

         List parts for current upload(列出当前上载的部件)
        //ListPartsRequest listPartRequest = new ListPartsRequest
        //{
        //    BucketName = _configuration["MinIO:Bucket"],
        //    Key = key,
        //    UploadId = initResponse.UploadId
        //};
        //ListPartsResponse listPartResponse = await amazonS3Client.ListPartsAsync(listPartRequest);
        //Debug.Assert(listPartResponse.Parts.Count == partCount);
        //TimeSpan ts3 = sw.Elapsed;
        //sw.Restart();

        // Complete the multipart upload  合并上传
        CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest
        {
            BucketName = _configuration["MinIO:Bucket"],
            Key = key,
            UploadId = initResponse.UploadId,
            PartETags = partETagList
        };
        CompleteMultipartUploadResponse compResponse = await amazonS3Client.CompleteMultipartUploadAsync(compRequest);
        TimeSpan ts4 = sw.Elapsed;
        sw.Restart();

        return Ok(new { Success = true, Message = "" });
    }
    catch (Exception ex)
    {
        return Ok(new { Success = true, Message = ex.Message });
    }
}
#endregion 后端进行分片上传示例


http://www.niftyadmin.cn/n/5314171.html

相关文章

GSP算法在数据挖掘中的应用

文章目录 一&#xff1a;基本概念介绍二&#xff1a;从一个样例入手三 论文中定义的一些细节四&#xff1a;GSP算法五.算法六 源代码及数据集等总结七. 参考文章 一&#xff1a;基本概念介绍 序列模式挖掘&#xff1a;指挖掘相对时间或其他模式出现频率高的模式 序列模式挖掘…

Python面试题(基础篇)

题目001: 在Python中如何实现单例模式。 点评&#xff1a;单例模式是指让一个类只能创建出唯一的实例&#xff0c;这个题目在面试中出现的频率极高&#xff0c;因为它考察的不仅仅是单例模式&#xff0c;更是对Python语言到底掌握到何种程度&#xff0c;建议大家用装饰器和元类…

uniapp自定义顶部导航并解决打包成apk后getMenuButtonBoundingClientRect方法失效问题

需求&#xff1a;要在app上的顶部导航提示哪里添加一些东西进去&#xff0c;用uniapp自带的肯定不行啊&#xff0c;所以自定义了所有的页面的顶部导航&#xff0c;之后自定义后用手机调试发现 uni.getMenuButtonBoundingClientRect()这个方法的top获取不到....网上找了很多种方…

.NetCore部署微服务(二)

目录 前言 概念 一 Consul注册服务中心 1.1 consul下载 1.2 consul运行 二 服务注册 2.1 安装Consul包 2.2 修改配置文件 2.3 注入Consul服务 2.3 修改Controller&#xff0c;增加HealthCheck方法 三 运行服务 3.1 docker运行服务 前言 上一篇讲到微服务要灵活伸缩…

intellij idea导入别人项目版本问题解决方案

当导入别人的项目太慢,原因是gradle版本不一致,这时android studio自动下载匹配的gradle版本导致长时间下载的问题。原因主要还是&#xff1a;这个下载地址是国外的&#xff0c;需要翻墙&#xff0c;否则会特别慢。 1.一般下载下来的项目都有这些文件夹&#xff0c;在导入项目…

HTML---JQurey的基本使用

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 本章目标 &#xff08;1&#xff09;能够搭建jQuery开发环境 &#xff08;2&#xff09;使用ready( )方法加载页面、掌握jQuery语法 使用addClass( )方法和css( )方法为元素添加CSS样式使用n…

07、Kafka ------ 消息生产者(演示 发送消息) 和 消息消费者(演示 监听消息)

目录 Kafka --- 消息生产者★ 消息★ 消息的分发机制★ 分发到哪个分区★ 轮询策略&#xff08;round-robin&#xff09;★ 使用命令行工具发送消息演示添加消息 Kafka --- 消息消费者★ 消息消费者命令▲ 监听 【指定主题】 的所有消息:▲ 监听 【指定主题、指定分区】的所有消…

扩展边界opencv

扩展图像的边缘&#xff08;如上边增加50像素&#xff09;通常是通过添加额外的像素行来实现的 使用cv2.copyMakeBorder函数 valueborder_color指定了边框的颜色 import cv2 import numpy as np# 读取图像 image cv2.imread(th.jpg)# 设置边框宽度 top_border_width 50 # …