.net 5 七牛云 的封装类

本文档展示了如何使用C#实现七牛云存储服务,包括获取上传凭证、图片压缩、文件上传、大文件分片上传等功能。还涵盖了错误处理和文件批量压缩入压缩包的操作。
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Qiniu.Http;
using Qiniu.Storage;
using Qiniu.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace Luoye
{

    public class ImageInfo
    {
        public int size { set; get; }
        public string format { set; get; }
        public int width { set; get; }
        public int height { set; get; }
        public string colorModel { set; get; }
        public int code { set; get; }
        public string error { set; get; }
    }
    public class QiniuSettings
    {
        public string AccessKey { set; get; }
        public string SecretKey { set; get; }
        public string Bucket { set; get; }
        public int Expires { set; get; }
        public string Url { set; get; }
    }
    public class QiniuService
    {
        private string _token;
        public string Token
        {
            set
            {
                _token = value;
            }
            get
            {
                _token = _token ?? GetUploadToken(null);
                return _token;
            }
        }
        public static string Url { set; get; }
        static QiniuService()
        {
            var builder = new ConfigurationBuilder()
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("appsettings.json").Build();
            Setting = builder.GetSection("QiniuService").Get<QiniuSettings>();
            Url = Setting.Url;
        }
        protected static QiniuSettings Setting { set; get; }
        protected Mac Mac { set; get; }
        public QiniuService()
        {
            Mac = new Mac(Setting.AccessKey, Setting.SecretKey);
        }
        public QiniuService(QiniuSettings setting)
        {
            lock (Setting)
            {
                Setting = setting;
                Url = Setting.Url;
            }
        }

        private static Regex qiNiuUrlRegex = new Regex(@"^ 地址*", RegexOptions.IgnoreCase);
        /// <summary>
        /// 七牛图片压缩预处理
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string QiNiuUrlCompress(string url)
        {
            url = url.Trim();
            //  ValidateHelper.IsTrue(url.IsNullOrEmpty() || !url.StartsWith("http", StringComparison.OrdinalIgnoreCase), "图片参数错误");
            url = url.Replace(@"\", "/");
            if (qiNiuUrlRegex.IsMatch(url) && !url.Contains("?"))
                url += "?imageslim";
            return url;
        }

        public string GetUploadToken(string bucket)
        {
            bucket = bucket ?? Setting.Bucket;
            PutPolicy putPolicy = new PutPolicy();
            putPolicy.Scope = bucket;
            putPolicy.SetExpires(Setting.Expires);
            Token = Auth.CreateUploadToken(Mac, putPolicy.ToJsonString());
            return Token;
        }

        public string UploadFile(byte[] byteArr)
        {
            var saveKey = Guid.NewGuid().ToString();
            FormUploader fu = new FormUploader(new Config());
            var result = fu.UploadData(byteArr, saveKey, Token, new PutExtra());
            if (result.Code == 200)
                return Setting.Url + "/" + saveKey;
            else
                return null;
        }



        /// <summary>
        /// 本地文件上传
        /// </summary>
        /// <param name="localFile"></param>
        /// <returns></returns>
        public string UploadFile(string localFile, string saveKey = "")
        {
            if (!System.IO.File.Exists(localFile))
            {
                throw new Exception(string.Format("{0} does not exist", localFile));
            }
            using (FileStream stream = new FileStream(localFile, FileMode.Open))
            {
                return UploadFile(stream, saveKey);
            }
        }
        public string FetchNetworkFiles(string url, string newUrl = null)
        {
            var saveKey = newUrl ?? Guid.NewGuid().ToString();
            BucketManager bucketManager = new BucketManager(Mac, new Config());

            var result = bucketManager.Fetch(url, Setting.Bucket, saveKey);
            if (result.Code == 200)
                return Setting.Url + "/" + saveKey;
            else
                return null;
        }

        public string UploadFile(Stream stream)
        {
            return UploadFile(stream, "");
        }

        public string UploadFile(Stream stream, string saveKey)
        {
            if (string.IsNullOrEmpty(saveKey))
            {
                saveKey = Guid.NewGuid().ToString();
            }
            Func<string, HttpResult> upload = (key) => {
                stream.Seek(0, SeekOrigin.Begin);
                stream.Position = 0;
                return new FormUploader(new Config()).UploadStream(stream, saveKey, Token, new PutExtra());
            };
            var result = upload(saveKey);
            if (result.Code == 200)
                return Setting.Url + "/" + saveKey;
            else if (result.Code == 401)
            {
                Token = null;
                result = upload(saveKey);
                if (result.Code == 200)
                    return Setting.Url + "/" + saveKey;
                else
                {
                    // LogHelper.Instance.Error($"七牛图片上传失败 HttpResult:{JsonHelper.SerializeObject(result)}", "QiNiu", "UdxService.Import");
                    return null;
                }
            }
            else
            {
                //  LogHelper.Instance.Error($"七牛图片上传失败 HttpResult:{JsonHelper.SerializeObject(result)}", "QiNiu", "UdxService.Import");
                return null;
            }
        }

        /// <summary>
        /// 上传大文件,可以从上次的断点位置继续上传
        /// </summary>
        public string UploadBigFile(string localFile)
        {
            // 这个示例单独使用了一个Settings类,其中包含AccessKey和SecretKey
            // 实际应用中,请自行设置您的AccessKey和SecretKey
            var saveKey = Guid.NewGuid().ToString();
            // 断点记录文件,可以不用设置,让SDK自动生成,如果出现续上传的情况,SDK会尝试从该文件载入断点记录
            // 对于不同的上传任务,请使用不同的recordFile
            // 包含两个参数,并且都有默认值
            // 参数1(bool): uploadFromCDN是否从CDN加速上传,默认否
            // 参数2(enum): chunkUnit上传分片大小,可选值128KB,256KB,512KB,1024KB,2048KB,4096KB
            //   ResumableUploader ru = new ResumableUploader(false, ChunkUnit.U1024K);

            ResumableUploader ru = new ResumableUploader(new Config() { ChunkSize = ChunkUnit.U1024K, UseCdnDomains = false });
            //  int maxTry = 4;

            PutExtra putExtra = new PutExtra() { MaxRetryTimes = 4 };
            // 使用默认进度处理,使用自定义上传控制            
            UploadProgressHandler upph = new UploadProgressHandler(ResumableUploader.DefaultUploadProgressHandler);
            //   UploadController upctl = new UploadController(uploadControl);
            //   UploadController upctl = new UploadController( );
            HttpResult result = ru.UploadFile(localFile, saveKey, Token, putExtra);
            if (result.Code == 200)
                return Setting.Url + "/" + saveKey;
            else if (result.Code == 401)
            {
                Token = null;
                result = ru.UploadFile(localFile, saveKey, Token, putExtra);
                if (result.Code == 200)
                    return Setting.Url + "/" + saveKey;
                else
                {
                    //   LogHelper.Instance.Error($"七牛图片分片上传失败 HttpResult:{JsonHelper.SerializeObject(result)}", "QiNiu", "UdxService.Import");
                    return null;
                }
            }
            else
            {
                //  LogHelper.Instance.Error($"七牛图片分片上传失败 HttpResult:{JsonHelper.SerializeObject(result)}", "QiNiu", "UdxService.Import");
                return null;
            }
        }

        // 内部变量,仅作演示
        private static bool paused = false;
        /// <summary>
        /// 上传控制
        /// </summary>
        /// <returns></returns>
        //private static UPTS uploadControl()
        //{
        //    // 这个函数只是作为一个演示,实际当中请根据需要来设置
        //    // 这个演示的实际效果是“走走停停”,也就是停一下又继续,如此重复直至上传结束
        //    paused = !paused;
        //    if (paused)
        //    {
        //        return UPTS.Suspended;
        //    }
        //    else
        //    {
        //        return UPTS.Activated;
        //    }
        //}

        /// <summary>
        /// 大量文件压缩
        /// </summary>
        /// <param name="txtKey">索引地址</param>
        /// <param name="prefix">压缩包文件</param>
        public UpdateResult mkzip(string txtKey, string prefix)
        {
            UpdateResult model = new UpdateResult();
            //string url = "";
            //默认utf-8,但是中文显示乱码,修改为gbk
            //"encoding/" + Qiniu.Util.Base64.UrlSafeBase64Encode("gbk") + 
            String fops = "mkzip/4/|saveas/" + Qiniu.Util.Base64.UrlSafeBase64Encode("open" + ":" + prefix);

            OperationManager operater = new OperationManager(Mac, new Config());

            //StringMap params = new StringMap();
            //压缩完成后,七牛回调URL
            //params.put("notifyURL", NOTIFY_URL);

            PfopResult Result = operater.Pfop("open", txtKey, fops, null, null, true);
            if (Result.Code == (int)HttpCode.OK)//200表示成功,否则就看报错信息
            {

                // String purl = "http://api.qiniu.com/status/get/prefop?id=" + Result.PersistentId;
                model.Url = Setting.Url + "/" + prefix;
                model.PersistentId = Result.PersistentId;
            }
            return model;
        }

        /// <summary>
        /// 将图片批量压缩入压缩包
        /// </summary>
        /// <param name="PicUrls">图片地址列表</param>
        /// <param name="PicAliasNames">图片别名</param>
        /// <param name="FileName">压缩包文件名</param>
        /// <returns></returns>
        public UpdateResult GetPicDownLodeUrlBag(List<CompressPicBag> CompressPicBagList, string FileName)
        {
            UpdateResult model = null;
            int MaxNum = 3000;

            //string Url = "";
            string indexUrl;
            StringBuilder strTxt = new StringBuilder();
            //int i = 0;
            foreach (var item in CompressPicBagList)
            {
                //strTxt.AppendLine($"/url/{Qiniu.Util.Base64.UrlSafeBase64Encode(item.PicUrl)}/alias/{Qiniu.Util.Base64.UrlSafeBase64Encode("/1/"+item.AliasName + ".JPG")}");
                strTxt.AppendLine($"/url/{Qiniu.Util.Base64.UrlSafeBase64Encode(item.PicUrl)}/alias/{Qiniu.Util.Base64.UrlSafeBase64Encode(item.AliasName + ".JPG")}");
            }
            using (MemoryStream ms = new MemoryStream())
            {
                using (StreamWriter sr = new StreamWriter(ms))
                {
                    //写入流
                    sr.Write(strTxt.ToString());
                    //将数据从缓存区刷新
                    sr.Flush();
                    //刷新后指针在尾巴上,要指到开始,不然数据为空
                    ms.Position = 0;
                    indexUrl = this.UploadFile(ms);
                    model = this.mkzip(indexUrl.Replace(QiniuService.Url + "/", ""), FileName + ".zip");
                }
            }
            return model;
        }
        public Dictionary<string, string> ErrCodeDic = new Dictionary<string, string>()
            {
                { "0", "成功" },
                { "1", "等待处理" },
                { "2", "正在处理"},
                { "3", "处理失败"},
                { "4", "通知提交失败"}
            };
        public string GetFileUploadStatus(string PersistentId)
        {
            string url = "http://api.qiniu.com/status/get/prefop";
            string data = "id=" + PersistentId;
            string result = this.HttpGet(url, data);
            UpdateStatus status = JsonConvert.DeserializeObject<UpdateStatus>(result);
            return ErrCodeDic[status.code];
        }
        public string HttpGet(string Url, string postDataStr)
        {
            string retString = "";
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
                request.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true; };
                request.Method = "GET";
                request.ContentType = "text/html;charset=UTF-8";

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                retString = myStreamReader.ReadToEnd();
                myStreamReader.Close();
                myResponseStream.Close();
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("400"))
                {
                    return null;
                }
                throw new Exception(string.Format("url:{0}?{1},message:{2}", Url, postDataStr, ex.Message));
            }

            return retString;
        }

        #region 辅助类
        public class UpdateStatus
        {
            public string code { get; set; }
            public string desc { get; set; }
        }
        public class UpdateResult
        {
            public string Url { get; set; }
            public string PersistentId { get; set; }
        }
        public class CompressPicBag
        {
            public string PicUrl { get; set; }
            public string AliasName { get; set; }
        }
        #endregion
    }
}


配置

  "QiniuService": {
    "AccessKey": " ",
    "SecretKey": "",
    "Bucket": "open",
    "Expires": 43200, //12*60*60 单位:秒
    "Url": "https://sXXXX.com"
  },
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落叶@Henry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值