//封装类代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Qiniu.Conf; using Qiniu.RS; using Qiniu.RPC; using Qiniu.RSF; using Qiniu.IO; using Qiniu.IO.Resumable; using System.IO; using System.Web; using System.Drawing.Imaging; using Qiniu.FileOp; using System.Net; //要先引用qiniu的dll文件 namespace ypsuit.common.QiniuHelper { public class QiniuHelper { /// <summary> /// cdnPath为网站服务器本地路径,本地备份一份,再上传到七牛空间一份 /// </summary> private static readonly string cdnPath = DataHelper.GetAbsolutePath(CommonFun.GetConfigData(DataConfigKey.Qiniu.ToString(), DataConfigAttr.CDN_PATH.ToString())); /// <summary> /// 空间名 /// </summary> public static readonly string bucket = CommonFun.GetConfigData(DataConfigKey.Qiniu.ToString(), DataConfigAttr.BUCKET.ToString()); /// <summary> /// 七牛外域名 /// </summary> public static readonly string Domain = CommonFun.GetConfigData(DataConfigKey.Qiniu.ToString(), DataConfigAttr.DOMAIN.ToString()); /// <summary> /// 在网站/程序初始化时调用一次 /// </summary> public static void Init() { //设置权限key Qiniu.Conf.Config.ACCESS_KEY = CommonFun.GetConfigData(DataConfigKey.Qiniu.ToString(), DataConfigAttr.ACCESS_KEY.ToString()); //设置密匙key Qiniu.Conf.Config.SECRET_KEY = CommonFun.GetConfigData(DataConfigKey.Qiniu.ToString(), DataConfigAttr.SECRET_KEY.ToString()); } #region 查看单个文件属性信息 /// <summary> /// 查看单个文件属性信息 /// </summary> /// <param name="bucket">七牛云存储空间名</param> /// <param name="key">文件key</param> public static void Stat(string bucket, string key) { RSClient client = new RSClient(); Entry entry = client.Stat(new EntryPath(bucket, key)); if (entry.OK) { Console.WriteLine("Hash: " + entry.Hash); Console.WriteLine("Fsize: " + entry.Fsize); Console.WriteLine("PutTime: " + entry.PutTime); Console.WriteLine("MimeType: " + entry.MimeType); Console.WriteLine("Customer: " + entry.Customer); } else { Console.WriteLine("Failed to Stat"); } } #endregion /// <summary> /// 复制单个文件 /// </summary> /// <param name="bucketSrc">需要复制的文件所在的空间名</param> /// <param name="keySrc">需要复制的文件key</param> /// <param name="bucketDest">目标文件所在的空间名</param> /// <param name="keyDest">标文件key</param> public static void Copy(string bucketSrc, string keySrc, string bucketDest, string keyDest) { RSClient client = new RSClient(); CallRet ret = client.Copy(new EntryPathPair(bucketSrc, keySrc, bucketDest, keyDest)); if (ret.OK) { Console.WriteLine("Copy OK"); } else { Console.WriteLine("Failed to Copy"); } } /// <summary> /// 移动单个文件 /// </summary> /// <param name="bucketSrc">需要移动的文件所在的空间名</param> /// <param name="keySrc">需要移动的文件</param> /// <param name="bucketDest">目标文件所在的空间名</param> /// <param name="keyDest">目标文件key</param> public static void Move(string bucketSrc, string keySrc, string bucketDest, string keyDest) { Console.WriteLine("\n===> Move {0}:{1} To {2}:{3}", bucketSrc, keySrc, bucketDest, keyDest); RSClient client = new RSClient(); new EntryPathPair(bucketSrc, keySrc, bucketDest, keyDest); CallRet ret = client.Move(new EntryPathPair(bucketSrc, keySrc, bucketDest, keyDest)); if (ret.OK) { Console.WriteLine("Move OK"); } else { Console.WriteLine("Failed to Move"); } } /// <summary> /// 删除单个文件 /// </summary> /// <param name="bucket">文件所在的空间名</param> /// <param name="key">文件key</param> public static void Delete(string bucket, string key) { //Console.WriteLine("\n===> Delete {0}:{1}", bucket, key); RSClient client = new RSClient(); CallRet ret = client.Delete(new EntryPath(bucket, key)); //if (ret.OK) //{ // Console.WriteLine("Delete OK"); //} //else //{ // Console.WriteLine("Failed to delete"); //} } /// <summary> /// 批量获取文件信息 /// </summary> /// <param name="bucket"></param> /// <param name="keys"></param> public static void BatchStat(string bucket, string[] keys) { RSClient client = new RSClient(); List<EntryPath> EntryPaths = new List<EntryPath>(); foreach (string key in keys) { Console.WriteLine("\n===> Stat {0}:{1}", bucket, key); EntryPaths.Add(new EntryPath(bucket, key)); } client.BatchStat(EntryPaths.ToArray()); } /// <summary> /// 批量复制 /// </summary> /// <param name="bucket"></param> /// <param name="keys"></param> public static void BatchCopy(string bucket, string[] keys) { List<EntryPathPair> pairs = new List<EntryPathPair>(); foreach (string key in keys) { EntryPathPair entry = new EntryPathPair(bucket, key, Guid.NewGuid().ToString()); pairs.Add(entry); } RSClient client = new RSClient(); client.BatchCopy(pairs.ToArray()); } /// <summary> /// 批量移动 /// </summary> /// <param name="bucket"></param> /// <param name="keys"></param> public static void BatchMove(string bucket, string[] keys) { List<EntryPathPair> pairs = new List<EntryPathPair>(); foreach (string key in keys) { EntryPathPair entry = new EntryPathPair(bucket, key, Guid.NewGuid().ToString()); pairs.Add(entry); } RSClient client = new RSClient(); client.BatchMove(pairs.ToArray()); } /// <summary> /// 批量删除 /// </summary> /// <param name="bucket"></param> /// <param name="keys"></param> public static void BatchDelete(string bucket, string[] keys) { RSClient client = new RSClient(); List<EntryPath> EntryPaths = new List<EntryPath>(); foreach (string key in keys) { //Console.WriteLine("\n===> Stat {0}:{1}", bucket, key); EntryPaths.Add(new EntryPath(bucket, key)); } client.BatchDelete(EntryPaths.ToArray()); } /// <summary> /// 列出所有文件信息 /// </summary> /// <param name="bucket"></param> public static List<DumpItem> List(int limit = 100, string prefix = "") { RSFClient rsf = new RSFClient(bucket); rsf.Prefix = prefix; rsf.Limit = limit; List<DumpItem> list = new List<DumpItem>(); List<DumpItem> items; while ((items = rsf.Next()) != null) { list.AddRange(items); //todo } return list; } /// <summary> /// 普通上传文件 /// key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误 /// </summary> /// <param name="bucket"></param> /// <param name="key">上传后的路径</param> /// <param name="fname">要上传的文件路径(文件必须存在)</param> public static PutRet PutFile(string key, string fname) { if (key.IndexOf('.') == -1) key += Path.GetExtension(fname); var policy = new PutPolicy(bucket, 3600); string upToken = policy.Token(); PutExtra extra = new PutExtra(); IOClient client = new IOClient(); //client.PutFinished += (o, retTemp) => //{ // if (retTemp.StatusCode == HttpStatusCode.OK) // { // } // else if (retTemp.StatusCode == HttpStatusCode.BadGateway || // retTemp.StatusCode == HttpStatusCode.BadRequest || // retTemp.StatusCode == HttpStatusCode.GatewayTimeout || // retTemp.StatusCode == HttpStatusCode.GatewayTimeout || // retTemp.StatusCode == HttpStatusCode.InternalServerError) // { // } //}; PutRet ret = client.PutFile(upToken, key, fname, extra); return ret; } /// <summary> /// 普通上传图片 /// key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误 /// </summary> /// <param name="bucket"></param> /// <param name="key">上传后的路径</param> /// <param name="fname">要上传的文件路径(文件必须存在)</param> public static PutRet PutImage(string key, string fname, string mimeType = "image/jpg") { if (key.IndexOf('.') == -1) key += Path.GetExtension(fname); if (mimeType == "") mimeType = GetMimeTypeByExtension(Path.GetExtension(fname)); var policy = new PutPolicy(bucket, 3600); string upToken = policy.Token(); PutExtra extra = new PutExtra { MimeType = mimeType, Crc32 = 123, CheckCrc = CheckCrcType.CHECK, Params = new Dictionary<string, string>() }; IOClient client = new IOClient(); PutRet ret = client.PutFile(upToken, key, fname, extra); return ret; } /// <summary> /// 上传文件到网站服务器,再上传到七牛服务器 /// </summary> /// <param name="fileData">页面/swf传过来的文件数据</param> /// <param name="fileType">预留</param> /// <param name="path">文件加逻辑路径,如:images/ </param> /// <param name="isOriginal">是否保留文件原名</param> /// <param name="prefix">不保留原名时,文件名的前缀部分</param> /// <returns></returns> public static PutRet UploadFile(HttpPostedFileBase fileData, string fileType = "", string path = "", string isOriginal = "",string prefix="") { PutRet ret = null; if (fileData != null) { var fileExt = Path.GetExtension(fileData.FileName); var fileName = ""; if (isOriginal != "1") { fileName = DataHelper.CreateRandomName(fileExt); if (prefix != "") fileName = prefix + fileName; } else fileName = Path.GetFileName(fileData.FileName).Replace(" ", ""); var fileFullPath = ""; bool isImage = false; string mimeType = GetMimeTypeByExtension(fileExt); if (mimeType == "") { if (path.Len() == 0) path = "files/"; fileFullPath = Path.Combine(path, fileType); } else if (mimeType.StartsWith("image")) { if (path.Len() == 0) path = "images/"; fileFullPath = Path.Combine(path, fileType); isImage = true; } else { if (path.Len() == 0) path = "other/"; fileFullPath = Path.Combine(path, fileType); } if (!Directory.Exists(cdnPath + fileFullPath)) { Directory.CreateDirectory(cdnPath + fileFullPath); } var fileFullName = cdnPath + fileFullPath + "/" + fileName; fileData.SaveAs(fileFullName); string key = string.Empty; //上传图片到七牛 if (System.IO.File.Exists(fileFullName)) { // long len = fileData.ContentLength / 1024; key = fileFullName.Replace(cdnPath, "").Replace("\\", "/").Replace("//", "/"); if (isImage) ret = PutImage(key, fileFullName, mimeType); else ret = PutFile(key, fileFullName); } } return ret; } /// <summary> /// 通过后缀获取mime类型 /// </summary> /// <param name="extension"></param> /// <returns></returns> private static string GetMimeTypeByExtension(string extension) { string mimeType = ""; extension = extension.TrimStart('.').ToLowerInvariant(); switch (extension) { case "gif": mimeType = "image/gif"; break; case "png": mimeType = "image/png"; break; case "bmp": mimeType = "image/bmp"; break; case "jpeg": case "jpg": mimeType = "image/jpg"; break; } return mimeType; } /// <summary> /// 断点续传 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="fname"></param> public static void ResumablePutFile(string bucket, string key, string fname) { Console.WriteLine("\n===> ResumablePutFile {0}:{1} fname:{2}", bucket, key, fname); PutPolicy policy = new PutPolicy(bucket, 3600); string upToken = policy.Token(); Settings setting = new Settings(); ResumablePutExtra extra = new ResumablePutExtra(); // extra.Notify += PutNotifyEvent;//(int blkIdx, int blkSize, BlkputRet ret);//上传进度通知事件 ResumablePut client = new ResumablePut(setting, extra); client.PutFile(upToken, fname, Guid.NewGuid().ToString()); } /// <summary> /// 得到文件的外链地址 /// </summary> /// <param name="key"></param> /// <param name="isPublic"></param> /// <returns></returns> public static string GetUrl(string key, bool isPublic = true) { string baseUrl = GetPolicy.MakeBaseUrl(Domain, key); if (isPublic) return baseUrl; string private_url = GetPolicy.MakeRequest(baseUrl); return private_url; } /// <summary> /// 获取图片信息 /// </summary> /// <param name="key"></param> /// <param name="isPublic"></param> /// <returns></returns> public static ImageInfoRet GetImageInfo(string key, bool isPublic = true) { string url = GetPolicy.MakeBaseUrl(Domain, key); //生成fop_url string imageInfoURL = ImageInfo.MakeRequest(url); //对其签名,生成private_url。如果是公有bucket此步可以省略 if (!isPublic) imageInfoURL = GetPolicy.MakeRequest(imageInfoURL); ImageInfoRet infoRet = ImageInfo.Call(imageInfoURL); if (infoRet.OK) { Console.WriteLine("Format: " + infoRet.Format); Console.WriteLine("Width: " + infoRet.Width); Console.WriteLine("Heigth: " + infoRet.Height); Console.WriteLine("ColorModel: " + infoRet.ColorModel); } else { Console.WriteLine("Failed to ImageInfo"); } return infoRet; } public static string GetImagePreviewUrl(string key, bool isPublic = true) { string url = GetPolicy.MakeBaseUrl(Domain, key); ImageView imageView = new ImageView { Mode = 0, Width = 200, Height = 200, Quality = 90, Format = "jpg" }; string viewUrl = imageView.MakeRequest(url); if (!isPublic) viewUrl = GetPolicy.MakeRequest(viewUrl);//私链 return viewUrl; } /// <summary> /// 获取水印图片 /// </summary> /// <param name="key"></param> /// <param name="type"></param> /// <param name="waterString"></param> /// <param name="isPublic"></param> /// <param name="waterColor"></param> /// <returns></returns> public static string GetWaterMarker(string key, WaterType type = WaterType.No, string waterString = "", bool isPublic = true, string waterColor = "red") { string url = GetUrl(key); string markerUrl = string.Empty; switch (type) { case WaterType.Text: { //文字水印 WaterMarker marker = new TextWaterMarker(waterString, "", waterColor); markerUrl = marker.MakeRequest(url); } break; case WaterType.Image: { //图片水印 WaterMarker marker = new ImageWaterMarker(waterString); markerUrl = marker.MakeRequest(url); } break; } if (!isPublic && !string.IsNullOrEmpty(markerUrl)) markerUrl = GetPolicy.MakeRequest(markerUrl); return markerUrl; } /// <summary> /// 水印类型枚举 /// </summary> public enum WaterType { /// <summary> /// 无水印 /// </summary> No, /// <summary> /// 文字水印 /// </summary> Text, /// <summary> /// 图片水印 /// </summary> Image } } }
.Net MVC控制器调用上传:
/// <summary> /// 上传文件到七牛服务器 /// </summary> /// <param name="fileData"></param> /// <param name="uploadDir">目录</param> /// <param name="original">是否保留原名(1:保留,其他不保留)</param> /// <returns></returns> public ActionResult UploadFile(HttpPostedFileBase fileData, string uploadDir = "", string isOriginal = "") { Qiniu.IO.PutRet ret = QiniuHelper.UploadFile(fileData, "", uploadDir, isOriginal); if (ret != null && ret.StatusCode == HttpStatusCode.OK) { QiniuFile newFile = new QiniuFile() { FileKey = ret.key, Hash = ret.Hash, FSize = fileData.ContentLength, Mime = "application/file", PutTime = DateTime.Now, CreatedById = LoginId }; Contract.Add(newFile); } return Json(ret); }
.NET MVC页面使用 uploadify进行文件上传(uploadify插件我就不详细说了,这里是简单说下使用方法,说太多了就没研究价值了 ):
@model ypsuit.model.QiniuFile @using System.Web.Mvc @using System.Web.Mvc.Html @using ypsuit.common @{ string QiniuUrl = CommonFun.GetConfigData(DataConfigKey.QiniuUrl.ToString()); Layout = null; } @using (Ajax.BeginForm("UploadFile", "QiniuFile", new AjaxOptions { HttpMethod = "POST", OnSuccess = "editSuccess" }, new { @class = "form-horizontal", id = "form-create" })) { <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button> <h4 class="modal-title">添加七牛文件</h4> </div> <div class="modal-body"> <div class="form-group"> <label class="control-label col-md-3" for="uploadDir">上传目录</label> <span style="color:red"></span> <div class="col-md-8"> <input type="text" id="uploadDir" value="" placeholder="不填自动选择目录" /> <input type="checkbox" value="1" name="isOriginal" id="isOriginal" checked="checked" />保留原名 </div> </div> <div class="form-group"> <label class="control-label col-md-3" for="file_upload_list">文件(可多选)</label> <span style="color:red"></span> <div class="col-md-8"> <input type="button" id="file_upload_list" value="请选择文件" /> </div> </div> <div class="form-group"> <label class="control-label col-md-3" for="file_upload_list">提示:</label> <span style="color:red"></span> <div class="col-md-8"> 上传成功后,随时可点击 从七牛服务器更新 获取最新的文件信息 </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal" id="btnClose">关闭窗口</button> </div> </div> } <script src="/Assets/plugins/uploadify-v3.1/jquery.uploadify-3.1.min.js"></script> <link href="@(QiniuUrl)/Assets/plugins/uploadify-v3.1/uploadify.css" rel="stylesheet" /> <script type="text/javascript"> $(function () { $('#file_upload_list').uploadify({ 'auto': true, 'buttonText': '请选择上传文件', 'fileTypeDesc': '静态文件', 'fileTypeExts': '*.gif; *.jpg; *.png; *.bmp; *.jpeg; *.tif;*.js;*.txt;*.mp3;', 'swf': "/assets/plugins/uploadify-v3.1/uploadify.swf?a=23", 'uploader': '/Admin/QiniuFile/UploadFile', 'multi': true, 'onUploadStart': function (file) { $("#file_upload_list").uploadify("settings", 'formData', { uploadDir: $("#uploadDir").val(), isOriginal: $("#isOriginal").is(":checked")?"1":"0" }); }, 'onUploadSuccess': function (file, data, response) { } }); }) </script>
最后出一张页面图:
附:
七牛开发文档中心:http://developer.qiniu.com/docs/v6/index.html
如果大家觉得不错,注册一个,我能得到点好处。
推荐注册地址: https://portal.qiniu.com/signup?code=3lqg1obz73y36
认证成为标准用户后,有很大好处,个人网站一般用不完: