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

开发环境

Win11

vs2022

appsettings.json添加配置项

cs 复制代码
  //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前缀
  }

注入代码

cs 复制代码
[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;
    }
    
    //。。。。。。

}

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

从官方考下来的代码示例

cs 复制代码
#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 后端进行分片上传示例

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

cs 复制代码
#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 后端进行分片上传示例
相关推荐
码农君莫笑2 天前
Blazor项目中使用EF读写 SQLite 数据库
linux·数据库·sqlite·c#·.netcore·人机交互·visual studio
_oP_i2 天前
.NET Core 项目配置到 Jenkins
运维·jenkins·.netcore
A^mber4 天前
基于.NetCore 的 AI 识别系统的设计与实现
人工智能·.netcore
Jeffrey~~6 天前
.Net_比对Json文件是否一致
c#·json·.net·.netcore
吳所畏惧6 天前
C#轻松实现Winform监控文件夹变化以及监控文件新增、修改、删除、重命名等操作保姆级详细教程
开发语言·windows·c#·.net·.netcore
CS软件开发框架6 天前
C/S软件授权注册系统-轻量级WebApi服务器介绍
运维·服务器·visualstudio·c#·.net·.netcore
鸠摩智首席音效师7 天前
如何使用 Docker 容器化 .NET Core 应用程序 ?
docker·容器·.netcore
洱海之月7 天前
.Net Core框架创建一个Windows服务类型的应用程序
.netcore
洱海之月7 天前
.Net Core配置使用Log4Net日志记录
.netcore
张3蜂7 天前
.NET Core 各版本特点、差异及适用场景详解
asp.net·.net·.netcore