首页 > 其他分享 >.netcore 对象存储帮助类

.netcore 对象存储帮助类

时间:2024-05-24 09:07:32浏览次数:24  
标签:存储 string objectName netcore 对象 request bucketName var new

说明:
1、由于各平台对象存储规则存在细微差异,故在类中对于入参进行处理(使用时需要根据自身情况调整)。
2、本文档写于2024年05月24日,由于版本的迭代,可能存在细微差异,可能导致错误,所以推荐下载文档使用NuGet引用版本进行测试。

minio对象存储帮助类
using Minio;
using Minio.DataModel;
using Minio.Exceptions;

namespace Zowie.Common.Helper
{
    /// <summary>
    /// Minio
    /// NuGet引用Minio.AspNetCore,版本:5.0.0
    /// </summary>
    public class MinioHelper
    {
        private MinioClient _minioClient;

        public MinioHelper()
        {
            var apiPath = "Endpoint";//例如:192.168.1.1:9000,这里不要带http或https
            var minioUser = "AccessKey";//minio账号
            var minioPwd = "SecretKey";//minio密码
            _minioClient = new MinioClient().WithEndpoint(apiPath).WithCredentials(minioUser, minioPwd).Build();
        }

        public MinioHelper(string apiPath, string minioUser, string minioPwd)
        {
            _minioClient = new MinioClient().WithEndpoint(apiPath).WithCredentials(minioUser, minioPwd).Build();
        }

        #region 操作存储桶
        /// <summary>
        /// 操作存储桶
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="loc">可选参数</param>
        /// <returns></returns>
        public async Task MakeBucket(string bucketName, string loc = "us-east-1")
        {
            try
            {
                bool found = await BucketExists(bucketName);
                if (found)
                {
                    throw new Exception(string.Format("存储桶[{0}]已存在", bucketName));
                }
                MakeBucketArgs args = new MakeBucketArgs()
                                       .WithBucket(bucketName)
                                       .WithLocation(loc);
                await _minioClient.MakeBucketAsync(args);
                //设置桶的访问权限(读、写、读和写)
                await SetPolicyAsync(bucketName, 3);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }


        /// <summary>
        /// 校验是否存在,如果不存在则报错
        /// </summary>
        /// <param name="bucketName"></param>
        private async Task CheckBucket(string bucketName)
        {
            bool found = await BucketExists(bucketName);
            if (!found)
            {
                await MakeBucket(bucketName);
                //throw new Exception(string.Format("存储桶[{0}]不存在", bucketName));
            }
        }

        /// <summary>
        /// 检查存储桶是否存在
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <returns></returns>
        public async Task<bool> BucketExists(string bucketName, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                BucketExistsArgs args = new BucketExistsArgs()
                                                .WithBucket(bucketName);

                return await _minioClient.BucketExistsAsync(args);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        #endregion 操作存储桶

        #region 操作文件对象

        /// <summary>
        /// 判断桶里,对应路径文件是否存在
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">存储桶里的对象名称,相对路径。例如/shouji/test.jpg</param>
        /// <returns></returns>
        public async Task<bool> FileExist(string bucketName, string objectName)
        {
            try
            {
                var obj = new StatObjectArgs().WithBucket(bucketName)
                                        .WithObject(objectName);
                await _minioClient.StatObjectAsync(obj);
            }
            catch (AggregateException e)
            {
                foreach (var item in e.InnerExceptions)
                {
                    if (item is ObjectNotFoundException notFound)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// 从桶下载文件到流
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称,相对路径。例如/shouji/test.jpg</param>
        /// <param name="sse"></param>
        /// <returns></returns>
        public async Task<ObjectStat> FGetObject(string bucketName, string objectName, IServerSideEncryption sse = null, Action<Stream> cb = null)
        {
            await CheckBucket(bucketName);

            try
            {
                GetObjectArgs args = new GetObjectArgs()
                                        .WithBucket(bucketName)
                                        .WithObject(objectName)
                                        .WithServerSideEncryption(sse)
                                        .WithCallbackStream(cb);
                return await _minioClient.GetObjectAsync(args);
            }
            catch (MinioException e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 从桶下载文件到本地
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objectName"></param>
        /// <param name="fileName"></param>
        /// <param name="sse"></param>
        /// <returns></returns>
        public async Task FGetObject(string bucketName, string objectName, string fileName, IServerSideEncryption sse = null)
        {
            await CheckBucket(bucketName);

            if (objectName.StartsWith('/'))
            {
                objectName = objectName.Substring(1);
            }

            fileName = fileName.Replace("\\", "/").Replace("//", "/");

            // 确保本地目录结构存在  
            string path = Path.GetDirectoryName(fileName);

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }

            GetObjectArgs args = new GetObjectArgs()
                                .WithBucket(bucketName)
                                .WithObject(objectName)//上传到minio服务器中生成的objectName
                                .WithFile(fileName);// D:\\photo.jpg
            await _minioClient.GetObjectAsync(args);
        }

        /// <summary>
        /// 根据本地相对路径上传到服务器对应的相对路径
        /// </summary>
        /// <param name="file">绝对路径。例如D:/Project/shouji/test.jpg</param>
        /// <param name="filePath">存储桶里的对象名称,相对路径。例如/shouji/test.jpg</param>
        /// <returns></returns>
        public async Task<bool> UploadFileForBendi(string bucketName, string file, string filePath, string contentType = "application/octet-stream")
        {
            string toPath = filePath.Replace($"/{bucketName}/", "").Replace($"{bucketName}/", "");

            //上传到MinIO中的文件名称
            string[] leftSplit = file.Split('/');
            string[] rightSplit = leftSplit[leftSplit.Length - 1].Split('\\');
            string objName = rightSplit[rightSplit.Length - 1];
            if (!string.IsNullOrEmpty(toPath))
            {
                if (toPath.Contains(objName))
                {
                    toPath = toPath.Replace(objName, "");
                }
                else if (toPath.Substring(toPath.Length - 1, 1) != "/")
                {
                    toPath += "/";
                }
            }
            objName = toPath + objName;
            bool result = await Task.Run(async () =>
            {
                try
                {
                    await CheckBucket(bucketName);

                    if (objName.ToLower().EndsWith(".png"))
                    {
                        contentType = "image/png";
                    }
                    else if (objName.ToLower().EndsWith(".jpg") || objName.ToLower().EndsWith(".jpeg"))
                    {
                        contentType = "image/jpeg";
                    }
                    else if (objName.ToLower().EndsWith(".gif"))
                    {
                        contentType = "image/gif";
                    }
                    else if (objName.ToLower().EndsWith(".mp4"))
                    {
                        contentType = "video/mp4";
                    }

                    byte[] bs = File.ReadAllBytes(file);
                    System.IO.MemoryStream filestream = new System.IO.MemoryStream(bs);

                    PutObjectArgs args = new PutObjectArgs()
                                        .WithBucket(bucketName)
                                        .WithObject("/" + objName)
                                        .WithStreamData(filestream)
                                        .WithContentType(contentType)
                                        .WithObjectSize(filestream.Length);
                    var ret = await _minioClient.PutObjectAsync(args);
                    filestream.Close();

                    return true;
                }
                catch (MinioException e)
                {
                    throw e;
                }
            });
            return result;
        }

        /// <summary>
        /// 上传本地文件至存储桶
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称,相对路径。例如/shouji/test.jpg</param>
        /// <returns></returns>
        public async Task FPutObject(string bucketName, string objectName, Stream stream, string contentType = "application/octet-stream", Dictionary<string, string> metaData = null, IServerSideEncryption sse = null)
        {
            await CheckBucket(bucketName);
            try
            {
                //var data= _minioClient.PutObjectAsync(bucketName, objectName, fileName, contentType: "application/octet-stream");
                PutObjectArgs args = new PutObjectArgs()
                                        .WithBucket(bucketName)
                                        .WithObject(objectName)
                                        .WithStreamData(stream)
                                        .WithContentType(contentType)
                                        .WithHeaders(metaData)
                                        .WithObjectSize(stream.Length)
                                        .WithServerSideEncryption(sse);
                var ret = await _minioClient.PutObjectAsync(args);
            }
            catch (MinioException e)
            {
                throw new Exception(e.Message);
            }
        }

        #endregion 操作文件对象

        #region 操作对象
        /// <summary>删除一个对象
        /// 删除一个对象
        /// </summary>
        /// <param name="minio">连接实例</param>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称</param>
        /// <returns></returns>
        public async Task RemoveObject(string bucketName, string objectName)
        {
            await CheckBucket(bucketName);

            try
            {
                RemoveObjectArgs args = new RemoveObjectArgs()
                                .WithBucket(bucketName)
                                .WithObject(objectName);
                await _minioClient.RemoveObjectAsync(args);
            }
            catch (MinioException e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>删除多个对象
        /// 删除多个对象
        /// </summary>
        /// <param name="minio">连接实例</param>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectsList">含有多个对象名称的IEnumerable</param>
        /// <returns></returns>
        public async Task<bool> RemoveObjects(string bucketName, List<string> objectsList)
        {
            await CheckBucket(bucketName);

            bool flag = false;
            try
            {
                if (objectsList != null)
                {
                    //IObservable<DeleteError> objectsOservable = await _minioClient.RemoveObjectAsync(bucketName, objectsList).ConfigureAwait(false);
                    flag = true;
                    //IDisposable objectsSubscription = objectsOservable.Subscribe(
                    //    objDeleteError => Console.WriteLine($"Object: {objDeleteError.Key}"),
                    //        ex => Console.WriteLine($"OnError: {ex}"),
                    //        () =>
                    //        {
                    //            Console.WriteLine($"Removed objects in list from {bucketName}\n");
                    //        });
                    //return;
                    RemoveObjectsArgs args = new RemoveObjectsArgs()
                                            .WithBucket(bucketName)
                                            .WithObjects(objectsList);
                    await _minioClient.RemoveObjectsAsync(args);
                }
            }
            catch (MinioException e)
            {
                throw new Exception(e.Message);
            }
            return flag;
        }

        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;
            SetPolicyArgs policyArgs = new SetPolicyArgs()
                    .WithBucket(bucketName)
                    .WithPolicy(policySet.Replace("BUCKETNAME", bucketName).Replace("BUCKETPREFIX", "*.*"));
            await _minioClient.SetPolicyAsync(policyArgs);
        }

        #endregion 操作对象

        /// <summary>生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
        /// 生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
        /// </summary>
        /// <param name="minio">连接实例</param>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称</param>
        /// <param name="expiresInt">失效时间(以秒为单位),默认是7天,不得大于七天</param>
        /// <param name="reqParams">额外的响应头信息,支持response-expires、response-content-type、response-cache-control、response-content-disposition</param>
        /// <returns></returns>
        public async Task<string> PresignedGetObject(string bucketName, string objectName, int expiresInt = 1000)
        {
            try
            {
                PresignedGetObjectArgs args = new PresignedGetObjectArgs()
                                            .WithBucket(bucketName)
                                            .WithObject(objectName)
                                            .WithExpiry(expiresInt);
                return await _minioClient.PresignedGetObjectAsync(args);
            }
            catch (Exception e)
            {
                return null;
            }
        }
    }
}
阿里云对象存储帮助类
using Aliyun.OSS;
using System.Text.RegularExpressions;

namespace Zowie.Common.Helper
{
    /// <summary>
    /// 阿里云OSS
    /// NuGet引用Aliyun.OSS.SDK.NetCore,版本:2.13.0
    /// </summary>
    public class ALiYunHelper
    {
        private OssClient client;

        public ALiYunHelper()
        {
            var endpoint = "Endpoint";
            var accessKey = "AccessKey";
            var secretKey = "SecretKey";
            client = new OssClient(endpoint, accessKey, secretKey);
        }

        // 创建一个存储桶
        public string CreateBucket(string? bucketName = null)
        {
            try
            {
                // 创建存储空间。
                var bucket = client.CreateBucket(bucketName);
                // 设置存储空间的读写权限为公共读。
                client.SetBucketAcl(bucketName, CannedAccessControlList.PublicRead);
                return ("Create bucket succeeded,  " + bucket.Name);
            }
            catch (Exception ex)
            {
                return ("Create bucket failed, " + ex.Message);
            }
        }

        /// <summary>
        /// 判断存储空间是否存在,不存在就创建,存在bug,未找到判断存储桶是否存在逻辑,这里如果目录里包含也会返回true
        /// </summary>
        /// <param name="bucketName">桶名</param>
        public void DoesBucketExist(string bucketName)
        {
            try
            {
                var exist = client.DoesBucketExist(bucketName);
                if (!exist)
                {
                    CreateBucket(bucketName);
                }
            }
            catch (Exception ex)
            {
                return;
            }
        }

        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="bucketName">填写Bucket名称,例如examplebucket</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="localFilename">绝对路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public bool UploadFile(string bucketName, string objectName, string localFilename)
        {
            //objectName = "shouji/chongqing/rongchang/2023/10/17/202310171501034B62CC.jpg";
            // 填写本地文件完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
            //localFilename = "C:/Users/Zowie/Desktop/1.png";
            try
            {
                if (objectName.StartsWith('/'))
                {
                    objectName = objectName.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                localFilename = rgx.Replace(localFilename, replacement);
                // 上传文件。
                var result = client.PutObject(bucketName, objectName, localFilename);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 存储一个字符串
        /// </summary>
        /// <param name="bucketName">存储空间名称</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="stream">字符内容</param>
        /// <returns></returns>
        public bool PutString(string bucketName, string objectName, Stream stream)
        {
            try
            {
                if (objectName.StartsWith('/'))
                {
                    objectName = objectName.Substring(1);
                }
                // 上传文件。
                client.PutObject(bucketName, objectName, stream);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }


        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="bucketName">存储空间名称</param>
        /// <param name="fileToUpload">文件路径。例如D:\\localpath\\examplefile.txt</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public bool PutObject(string bucketName, string fileToUpload, string objectName = "")
        {
            if (string.IsNullOrEmpty(objectName))
            {
                objectName = Path.GetFileName(fileToUpload);
            }
            try
            {
                // 上传文件。
                var result = client.PutObject(bucketName, objectName, fileToUpload);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public bool DeleteObject(string bucketName, string objectName)
        {
            try
            {
                if (objectName.StartsWith('/'))
                {
                    objectName = objectName.Substring(1);
                }
                // 删除文件。
                client.DeleteObject(bucketName, objectName);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;

        }

        /// <summary>
        /// 批量删除文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectNames">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public bool DeleteObjects(string bucketName, List<string> objectNames)
        {
            try
            {
                var quietMode = true;
                var request = new DeleteObjectsRequest(bucketName, objectNames, quietMode);
                // 删除多个文件。
                var result = client.DeleteObjects(request);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 获取文件列表
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <returns></returns>
        public List<OssObjectSummary> ListObjects(string bucketName)
        {
            var objectsList = new List<OssObjectSummary>();
            try
            {
                ObjectListing result = null;
                string nextMarker = string.Empty;
                do
                {
                    var listObjectsRequest = new ListObjectsRequest(bucketName)
                    {
                        Marker = nextMarker,
                    };
                    // 列举文件。
                    result = client.ListObjects(listObjectsRequest);
                    foreach (var summary in result.ObjectSummaries)
                    {
                        objectsList.Add(summary);
                    }
                    nextMarker = result.NextMarker;
                } while (result.IsTruncated);

            }
            catch (Exception ex)
            {
            }
            return objectsList;
        }

        /// <summary>
        /// 把指定的OSS文件下载到流
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="downloadFilename">填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public void GetObject(string bucketName, string objectName, string downloadFilename)
        {
            try
            {
                if (objectName.StartsWith('/'))
                {
                    objectName = objectName.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                downloadFilename = rgx.Replace(downloadFilename, replacement);
                // 下载文件到流。OssObject包含了文件的各种信息,如文件所在的存储空间、文件名、元信息以及一个输入流。
                var obj = client.GetObject(bucketName, objectName);
                using (var requestStream = obj.Content)
                {
                    byte[] buf = new byte[1024];
                    var fs = System.IO.File.Open(downloadFilename, FileMode.OpenOrCreate);
                    var len = 0;
                    // 通过输入流将文件的内容读取到文件或者内存中。
                    while ((len = requestStream.Read(buf, 0, 1024)) != 0)
                    {
                        fs.Write(buf, 0, len);
                    }
                    fs.Close();
                }
            }
            catch (Exception ex)
            {

            }
        }

        /// <summary>
        /// 把指定的OSS文件下载到流
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="downloadFilename">填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public MemoryStream GetObject(string bucketName, string objectName)
        {
            try
            {
                if (objectName.StartsWith('/'))
                {
                    objectName = objectName.Substring(1);
                }
                // 下载文件到流。OssObject包含了文件的各种信息,如文件所在的存储空间、文件名、元信息以及一个输入流。
                var obj = client.GetObject(bucketName, objectName);
                MemoryStream imageStream = new MemoryStream(obj.ResponseStream.ReadByte());
                return imageStream;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 产生带有签名的URI
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        public void GenerateIamgeUri(string bucketName, string objectName)
        {
            try
            {
                var process = "image/resize,m_fixed,w_100,h_100";
                var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
                {
                    Expiration = DateTime.Now.AddHours(1),
                    Process = process
                };

                // 产生带有签名的URI
                var uri = client.GeneratePresignedUri(req);

            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 判断文件是否存在
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objectName"></param>
        /// <returns></returns>
        public bool DoesObjectExist(string bucketName, string objectName)
        {
            try
            {
                // 判断文件是否存在。
                var exist = client.DoesObjectExist(bucketName, objectName);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 断点续传下载
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objectName"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool ResumableDownloadObject(string bucketName, string objectName, string fileName)
        {
            try
            {
                // 设置断点记录文件的完整路径,例如D:\\localpath\\examplefile.txt.dcp。
                // 只有当Object下载中断产生了断点记录文件后,如果需要继续下载该Object,才需要设置对应的断点记录文件。下载完成后,该文件会被删除。
                var checkpointDir = "D:\\localpath\\examplefile.txt.dcp";
                // 通过DownloadObjectRequest设置多个参数。
                DownloadObjectRequest request = new DownloadObjectRequest(bucketName, objectName, fileName)
                {
                    // 指定下载的分片大小,单位为字节。
                    PartSize = 8 * 1024 * 1024,
                    // 指定并发线程数。
                    ParallelThreadCount = 3,
                    // checkpointDir用于保存断点续传进度信息。如果某一分片下载失败,再次下载时会根据文件中记录的点继续下载。如果checkpointDir为null,断点续传功能不会生效,每次失败后都会重新下载。
                    CheckpointDir = checkpointDir,
                };
                // 断点续传下载。
                client.ResumableDownloadObject(request);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}

天翼云对象存储帮助类
using Amazon.S3;
using Amazon.S3.Model;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;

namespace Zowie.Common.Helper
{
    /// <summary>
    /// 天翼云OSS
    /// NuGet引用AWSSDK.Core版本:3.7.304.3,AWSSDK.S3版本3.7.308.2
    /// </summary>
    public class TYiYunHelper
    {
        private AmazonS3Client client;

        public TYiYunHelper()
        {
            var accessKey = "AccessKey";
            var secretKey = "SecretKey";
            System.Net.ServicePointManager.ServerCertificateValidationCallback +=
                                delegate (
                                object sender,
                                System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                X509Chain chain,
                                SslPolicyErrors sslPolicyErrors) // 自签名忽略认证
                                {
                                    return true;
                                };
            AmazonS3Config config = new AmazonS3Config();
            config.ServiceURL = "Endpoint"; // 指定IP和Port
            config.ForcePathStyle = true; // 使用路径模式
            config.SignatureVersion = "2"; // 签名版本
            client = new AmazonS3Client(accessKey, secretKey, config); // 建立连接
        }

        // 创建一个存储桶
        public async Task CreateBucket(string? bucketName = null)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName)) return;
                PutBucketRequest request = new PutBucketRequest();
                // 创建存储空间。
                request.BucketName = bucketName;
                // 设置存储空间的读写权限为公共读。
                request.CannedACL = S3CannedACL.PublicRead;
                PutBucketResponse response = await client.PutBucketAsync(request);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="bucketName">填写Bucket名称,例如examplebucket</param>
        /// <param name="key">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="filepath">绝对路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public async Task<bool> UploadFile(string bucketName, string key, string filepath)
        {
            try
            {
                if (key.StartsWith('/'))
                {
                    key = key.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                filepath = rgx.Replace(filepath, replacement);
                key = rgx.Replace(key, replacement);
                // 上传文件。
                var request = new PutObjectRequest();
                request.BucketName = bucketName;
                request.Key = key;
                request.CannedACL = S3CannedACL.PublicRead;
                request.FilePath = filepath;
                if (key.ToLower().EndsWith(".png"))
                {
                    request.ContentType = "image/png";
                }
                else if (key.ToLower().EndsWith(".jpg") || key.ToLower().EndsWith(".jpeg"))
                {
                    request.ContentType = "image/jpeg";
                }
                else if (key.ToLower().EndsWith(".gif"))
                {
                    request.ContentType = "image/gif";
                }
                else if (key.ToLower().EndsWith(".mp4"))
                {
                    request.ContentType = "video/mp4";
                }
                var result = await client.PutObjectAsync(request);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 存储一个字符串
        /// </summary>
        /// <param name="bucketName">填写Bucket名称,例如examplebucket</param>
        /// <param name="key">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="inputStream">字符内容</param>
        /// <returns></returns>
        public async Task<bool> PutString(string bucketName, string key, Stream inputStream)
        {
            try
            {
                if (key.StartsWith('/'))
                {
                    key = key.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                // 上传文件。
                var request = new PutObjectRequest();
                request.BucketName = bucketName;
                request.Key = key;
                request.CannedACL = S3CannedACL.PublicRead;
                request.InputStream = inputStream;
                if (key.ToLower().EndsWith(".png"))
                {
                    request.ContentType = "image/png";
                }
                else if (key.ToLower().EndsWith(".jpg") || key.ToLower().EndsWith(".jpeg"))
                {
                    request.ContentType = "image/jpeg";
                }
                else if (key.ToLower().EndsWith(".gif"))
                {
                    request.ContentType = "image/gif";
                }
                else if (key.ToLower().EndsWith(".mp4"))
                {
                    request.ContentType = "video/mp4";
                }
                var result = await client.PutObjectAsync(request);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="key">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public async Task<bool> DeleteObject(string bucketName, string key)
        {
            try
            {
                // 删除文件。
                var request = new DeleteObjectRequest();
                if (key.StartsWith('/'))
                {
                    key = key.Substring(1);
                }
                request.BucketName = bucketName;
                request.Key = key;
                request.BypassGovernanceRetention = true;
                DeleteObjectResponse response = await client.DeleteObjectAsync(request);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;
        }

        /// <summary>
        /// 批量删除文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectNames">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public async Task<bool> DeleteObjects(string bucketName, List<string> objectNames)
        {
            try
            {
                var request = new DeleteObjectsRequest();
                request.BucketName = bucketName;
                request.Quiet = false;
                foreach (var item in objectNames)
                {
                    request.AddKey(item);
                }
                request.BypassGovernanceRetention = true;
                DeleteObjectsResponse response = await client.DeleteObjectsAsync(request);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="key">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="filepath">填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public async Task GetObject(string bucketName, string key, string filepath)
        {
            try
            {
                if (key.StartsWith('/'))
                {
                    key = key.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                filepath = rgx.Replace(filepath, replacement);
                // 下载文件到流。OssObject包含了文件的各种信息,如文件所在的存储空间、文件名、元信息以及一个输入流。
                var obj = await client.GetObjectAsync(bucketName, key);
                using (Stream requestStream = obj.ResponseStream)
                {
                    byte[] buf = new byte[1024];

                    // 确保本地目录结构存在  
                    string path = Path.GetDirectoryName(filepath);

                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    var fs = System.IO.File.Open(filepath, FileMode.OpenOrCreate);
                    var len = 0;
                    // 通过输入流将文件的内容读取到文件或者内存中。
                    while ((len = requestStream.Read(buf, 0, 1024)) != 0)
                    {
                        fs.Write(buf, 0, len);
                    }
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 文件是否存在
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<bool> FileExist(string bucketName, string key)
        {
            try
            {
                if (key.StartsWith('/'))
                {
                    key = key.Substring(1);
                }
                var obj = await client.GetObjectAsync(bucketName, key);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
华为云对象存储帮助类
using OBS;
using OBS.Model;
using System.Text.RegularExpressions;

namespace Zowie.Common.Helper
{
    /// <summary>
    /// 华为云OBS
    /// NuGet引用esdk_obs_.net_core,版本:3.0.4
    /// </summary>
    public class HuaWeiOBSHelper
    {
        private ObsClient client;

        public HuaWeiOBSHelper()
        {
            ObsConfig config = new ObsConfig();
            config.Endpoint = "Endpoint";
            var accessKey = "AccessKey";
            var secretKey = "SecretKey";
            client = new ObsClient(accessKey, secretKey, config);
        }

        // 创建一个存储桶
        public string CreateBucket(string bucketName = null)
        {
            try
            {
                CreateBucketRequest request = new CreateBucketRequest()
                {
                    BucketName = bucketName,
                    CannedAcl = CannedAclEnum.PublicRead,
                };
                // 创建存储空间。
                var bucket = client.CreateBucket(request);
                return "Create bucket succeeded";
            }
            catch (Exception ex)
            {
                return "Create bucket failed, " + ex.Message;
            }
        }

        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="bucketName">填写Bucket名称,例如examplebucket</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="localFilename">绝对路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public bool UploadFile(string bucketName, string objectName, string localFilename)
        {
            try
            {
                if (objectName.StartsWith("/"))
                {
                    objectName = objectName.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                localFilename = rgx.Replace(localFilename, replacement);
                objectName = rgx.Replace(objectName, replacement);
                // 上传文件。
                var request = new PutObjectRequest()
                {
                    BucketName = bucketName,
                    ObjectKey = objectName,
                    CannedAcl = CannedAclEnum.PublicRead,
                    FilePath = localFilename
                };
                if (objectName.ToLower().EndsWith(".png"))
                {
                    request.ContentType = "image/png";
                }
                else if (objectName.ToLower().EndsWith(".jpg") || objectName.ToLower().EndsWith(".jpeg"))
                {
                    request.ContentType = "image/jpeg";
                }
                else if (objectName.ToLower().EndsWith(".gif"))
                {
                    request.ContentType = "image/gif";
                }
                else if (objectName.ToLower().EndsWith(".mp4"))
                {
                    request.ContentType = "video/mp4";
                }
                var result = client.PutObject(request);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 存储一个字符串
        /// </summary>
        /// <param name="bucketName">填写Bucket名称,例如examplebucket</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="inputStream">字符内容</param>
        /// <returns></returns>
        public bool PutString(string bucketName, string objectName, Stream inputStream)
        {
            try
            {
                if (objectName.StartsWith("/"))
                {
                    objectName = objectName.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                // 上传文件。
                var request = new PutObjectRequest()
                {
                    BucketName = bucketName,
                    ObjectKey = objectName,
                    CannedAcl = CannedAclEnum.PublicRead,
                    InputStream = inputStream
                };
                if (objectName.ToLower().EndsWith(".png"))
                {
                    request.ContentType = "image/png";
                }
                else if (objectName.ToLower().EndsWith(".jpg") || objectName.ToLower().EndsWith(".jpeg"))
                {
                    request.ContentType = "image/jpeg";
                }
                else if (objectName.ToLower().EndsWith(".gif"))
                {
                    request.ContentType = "image/gif";
                }
                else if (objectName.ToLower().EndsWith(".mp4"))
                {
                    request.ContentType = "video/mp4";
                }
                var result = client.PutObject(request);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public bool DeleteObject(string bucketName, string objectName)
        {
            try
            {
                if (objectName.StartsWith("/"))
                {
                    objectName = objectName.Substring(1);
                }
                // 删除文件。
                var request = new DeleteObjectRequest()
                {
                    BucketName = bucketName,
                    ObjectKey = objectName,
                };
                var response = client.DeleteObject(request);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;
        }

        /// <summary>
        /// 批量删除文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectNames">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <returns></returns>
        public bool DeleteObjects(string bucketName, List<string> objectNames)
        {
            try
            {
                var request = new DeleteObjectsRequest();
                request.BucketName = bucketName;
                request.Quiet = false;
                foreach (var item in objectNames)
                {
                    if (item.StartsWith("/"))
                        request.AddKey(item.Substring(1));
                    else
                        request.AddKey(item);

                }
                var response = client.DeleteObjects(request);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="bucketName">桶名</param>
        /// <param name="objectName">相对路径,相对路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。</param>
        /// <param name="filepath">填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt</param>
        /// <returns></returns>
        public void GetObject(string bucketName, string objectName, string filepath)
        {
            try
            {
                if (objectName.StartsWith("/"))
                {
                    objectName = objectName.Substring(1);
                }
                string pattern = @"\\|/";
                string replacement = @"/";
                Regex rgx = new Regex(pattern);
                filepath = rgx.Replace(filepath, replacement);
                // 下载文件到流。OssObject包含了文件的各种信息,如文件所在的存储空间、文件名、元信息以及一个输入流。
                var request = new GetObjectRequest()
                {
                    BucketName = bucketName,
                    ObjectKey = objectName,
                };
                var obj = client.GetObject(request);
                using (Stream requestStream = obj.OutputStream)
                {
                    byte[] buf = new byte[1024];

                    // 确保本地目录结构存在  
                    string path = Path.GetDirectoryName(filepath);

                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    var fs = File.Open(filepath, FileMode.OpenOrCreate);
                    var len = 0;
                    // 通过输入流将文件的内容读取到文件或者内存中。
                    while ((len = requestStream.Read(buf, 0, 1024)) != 0)
                    {
                        fs.Write(buf, 0, len);
                    }
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 文件是否存在
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objectName"></param>
        /// <returns></returns>
        public bool FileExist(string bucketName, string objectName)
        {
            try
            {
                if (objectName.StartsWith("/"))
                {
                    objectName = objectName.Substring(1);
                }
                var request = new GetObjectRequest()
                {
                    BucketName = bucketName,
                    ObjectKey = objectName,
                };
                var obj = client.GetObject(request);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

标签:存储,string,objectName,netcore,对象,request,bucketName,var,new
From: https://www.cnblogs.com/china-zhou/p/18209880

相关文章

  • Java面向对象-常用类(String 、StringBuffer 、StringBuilder的使用与深入)
    常用类-字符串相关类1什么是StringString是不可变类,即一旦一个String对象被创建,包含在这个对象中的字符序列是不可改变的,直至该对象被销毁。String类是final类,不能有子类。2分类StringStringBufferStringBuilder3String的使用packagecom.qf.string_c......
  • 零基础学Java第二十一天之IIO流之对象流
    IO流之对象流1、对象流1、理解将对象写入到文件,将文件里的对象读取到程序中classObjectInputStream–对象输入流classObjectOutputStream–对象输出流序列化/钝化:程序里的对象写入到文件中反序列化/活化:文件中的对象读取到程序中2、注意对象所属的类......
  • 【C++初阶】—— 类和对象 (上)
    ......
  • Viso的对象图形复制到word,发现图形画布底部有大量空白,如何解决
    1viso对象插入到wordVIso的图可以作为对象插入到word中,直接复制即可,复制后,可以在word中双击,关联到viso中,进行更改,很方便。正常情况下,在viso中做好图形后,直接复制到word中即可,在word中双击,关联到viso中。如下图:偶尔会存在一些格式比例大小的问题,导致对象下面很多空白,如下图:2......
  • netcore webapi部署到docker容器,api调用后显示中文乱码
    vs2022webapi部署到docker容器,api调用后显示中文乱码。原因是:源代码文件不是utf-8编码(用vscode打开是乱码,在vscode修改后,再提交,正常)解决方法:在中文环境下用过微软家Visualstudio的都知道,新建文件的保存编码都默认为当前系统语言,所以你的文件编码永远都是GB2312,非常令人蛋......
  • nodeJS 内置对象
    //const{log}=require("console");//const{argv}=require("process");//log(__dirname)//setImmediate(()=>{//log(__filename)//})//constbuffer=Buffer.from('a1','utf-8')//log(buffer)/......
  • MySQL 存储过程返回更新前记录
    在MySQL中,如果我们想在存储过程中返回更新前的记录,这通常不是直接支持的,因为UPDATE语句本身不返回更新前的数据。但是,我们可以通过一些策略来实现这个需求。1.MySQL存储过程返回更新前记录常用的方法策略以下是一个常见的策略:(1)使用临时表或表变量:在执行UPDATE之前,将需要更新的......
  • 面向对象(1)
    面向对象1面向对象思想概述回想这几天的内容,我们完成一个功能的步骤:先确定要做什么,然后分析怎么做。最后通过代码实现。我们在每一个具体步骤中都是一个参与者。这个就是面向过程的直接体现。面向过程的代表语言是C语言。如果需求变得复杂,每一步都要参与,就会变得比较麻烦。......
  • netcore 开源的与插件有关的项目
    在.NETCore生态系统中,有一些开源项目可以实现类似于插件系统的功能,允许应用程序动态加载和运行扩展或模块。以下是一些值得关注的项目和框架:1.OrchardCoreOrchardCore是一个开源、模块化的应用程序框架和内容管理系统,基于ASP.NETCore构建。它提供了强大的模块化和扩展......
  • JSP九大内置对象详解
    *JSP九大内置对象详解*JSP内置对象(9个内置对象):1.PageContextjavax.servlet.jsp.PageContextJSP的页面容器2.requestjavax.servlet.http.HttpServletrequest获取用户的请求信息3.responsejavax.servlet.http.HttpServletResponse服务器向客户端的回应信息4.sessionj......