C#使用七牛云存储上传下载文件、自定义回调

项目需要将音视频文件上传服务器,考虑并发要求高,通过七牛来实现。

做了一个简易的压力测试,同时上传多个文件,七牛自己应该有队列处理并发请求,我无论同时提交多少个文件,七牛是批量一个个排队处理了。

一个1.5MB的文件,上传时间大概2-3秒,感觉不错。 

 

直接上代码

 

using Qiniu.IO;
using Qiniu.IO.Resumable;
using Qiniu.RPC;
using Qiniu.RS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace qiniuTest
{/// <summary>/// 文件上传有两种方式:/// 一种是以普通方式直传文件,简称普通上传;/// 另一种方式是断点续上传,断点续上传在网络条件很一般的情况下也能有出色的上传速度,而且对大文件的传输非常友好。/// </summary>class Program{static string bucket = "cvteXXXX";static void Main(string[] args){Qiniu.Conf.Config.ACCESS_KEY = "6QQ7Cnz4bljdkQOWQ5UOAheVCAd0bCa7Tc5XXXXX";Qiniu.Conf.Config.SECRET_KEY = "9rUGnbFtvm-PLWcZeOR6ed9MUjZ4bKitf7YXXXX";string fileKey = "应用系统全貌图.png";//GetFileStat(bucket, fileKey);//小文件直传string fileName = "CVTE信息系统-业务功能架构图-IM和企业微信.jpg";//PutFile(bucket, Guid.NewGuid().ToString() + fileName, "d:\\" + fileName);//在asp.net mvc中的文件上传//ResumablePutFile(bucket, Guid.NewGuid().ToString(), Path.Combine(path, Request.Form[0]));//大文件上传//string bigFileName = "eclipse-java-luna-SR1-win32-x86_64.zip";//ResumablePutFile(bucket, Guid.NewGuid().ToString() + bigFileName, "d:\\Software\\" + bigFileName);//GetFile("7xq1c1.com1.z0.glb.clouddn.com", fileKey);//**********************  压力测试  **********************// 获取线程池的最大线程数和维护的最小空闲线程数int maxThreadNum, portThreadNum;int minThreadNum;ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);Console.WriteLine("最大线程数:{0}", maxThreadNum);Console.WriteLine("最小空闲线程数:{0}", minThreadNum);int loopNumber = 1; //内部循环次数int ConcurrentNumber = 10; //并发数for (int i = 0; i < ConcurrentNumber; i++){ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), loopNumber);}Console.ReadLine();}public static void TaskProc(object loopNumber){int LoopNumber = Convert.ToInt32(loopNumber);Console.WriteLine("启动任务,小文件直传");//小文件直传 压力测试for (int i = 0; i < LoopNumber; i++){string fileName = "WinRAR.exe";Console.WriteLine(i + "开始" + fileName + System.DateTime.Now);PutFile(bucket, Guid.NewGuid().ToString() + fileName, "D:\\" + fileName);Console.WriteLine(i + "完成" + fileName + System.DateTime.Now);string fileName1 = "WinRAR1.exe";Console.WriteLine(i + "开始" + fileName1 + System.DateTime.Now);PutFile(bucket, Guid.NewGuid().ToString() + fileName1, "D:\\" + fileName1);Console.WriteLine(i + "完成" + fileName1 + System.DateTime.Now);}}/// <summary>/// 查看单个文件属性信息/// </summary>/// <param name="bucket">七牛云存储空间名</param>/// <param name="key">文件key,也就是文件名</param>public static void GetFileStat(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");}}/// <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">文件key</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>/// <param name="key">您可以自行定义文件Key,一般GUID</param>/// <param name="fname">文件路径+文件名</param>public static void PutFile(string bucket, string key, string fname){var policy = new PutPolicy(bucket, 3600);string upToken = policy.Token();PutExtra extra = new PutExtra();IOClient client = new IOClient();client.PutFile(upToken, key, fname, extra);}/// <summary>/// 断点续上传方式,传大文件用这种方式/// </summary>/// <param name="bucket">文件所在的空间名</param>/// <param name="key">您可以自行定义文件Key,一般GUID</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();ResumablePut client = new ResumablePut(setting, extra);client.PutFile(upToken, fname, Guid.NewGuid().ToString());}/// <summary>/// Get方式获取文件/// </summary>/// <param name="domain">文件域</param>/// <param name="key">文件Key</param>public static void GetFile(string domain, string key){System.Diagnostics.Process.Start("http://" + domain + "/" + key);}}
}

 

另外,七牛的魔法变量非常强大,多用于增强回调

魔法变量

魔法变量是一组预先定义的变量,可以使用 $(var) 或 $(var.field_name) 形式求值。

目前可用的魔法变量如下:

变量名包含子项变量说明适用范围
bucket 获得上传的目标空间名。 
key 获得文件保存在空间中的资源名。 
etag 文件上传成功后的HTTP ETag。若上传时未指定资源ID,Etag将作为资源ID使用。 
fname 上传的原始文件名。不支持用于分片上传
fsize 资源尺寸,单位为字节。 
mimeType 资源类型,比如JPG图片的资源类型为image/jpg 
endUser 上传时指定的endUser字段,通常用于区分不同终端用户的请求。 
persistentId 音视频转码持久化的进度查询ID。 
exif获取所上传图片的Exif信息。

该变量包含子字段,比如对$(exif.ApertureValue.val)取值将得到该图片拍摄时的光圈值。

暂不支持用于saveKey
imageInfo获取所上传图片的基本信息。

该变量包含子字段,比如对$(imageInfo.width)取值将得到该图片的宽度。

暂不支持用于saveKey
year 上传时的年份。暂不支持用于’returnBody’、’callbackBody’中
mon 上传时的月份。暂不支持用于’returnBody’、’callbackBody’中
day 上传时的日期。暂不支持用于’returnBody’、’callbackBody’中
hour 上传时的小时。暂不支持用于’returnBody’、’callbackBody’中
min 上传时的分钟。暂不支持用于’returnBody’、’callbackBody’中
sec 上传时的秒钟。暂不支持用于’returnBody’、’callbackBody’中
avinfo音视频资源的元信息。暂不支持用于’saveKey’中
imageAve 图片主色调,算法由Camera360友情提供。 
ext 上传资源的后缀名,通过自动检测的 mimeType 或者原文件的后缀来获取。不支持用于分片上传
uuid 生成uuid暂不支持用于’saveKey’中
bodySha1 callbackBody的sha1(hex编码)只支持用于’callbackUrl’中

魔法变量支持$(<Object>.<Property>)形式的访问子项,例如:

  • $(<var>)
  • $(<var>.<field_name>)
  • $(<var>.<field_name>.<sub_field_name>)

求值举例:

  • $(bucket) - 获得上传目标bucket名字
  • $(imageInfo) - 获取当前上传图片的基本属性信息
  • $(imageInfo.height) - 获取当前上传图片的原始高度

回调通知(callback)

可以设置上传策略(PutPolicy)中的callbackUrl字段,并且设置callbackBody字段。

“自定义回调”具体实现

        /// <summary>/// 文件上传后的自定义回调/// </summary>/// <param name="bucket">文件所在的空间名</param>/// <param name="key">您可以自行定义文件Key,一般GUID</param>/// <param name="fname">文件路径+文件名</param>public static PutRet PutFile(string bucket, string key, string fname){var policy = new PutPolicy(bucket, 3600);policy.ReturnBody = "{\"key\": $(key), \"hash\": $(etag), \"extra\": $(x:extra), \"callbackUrl\": $(x:callbackUrl)}";//policy.CallBackBody = "name=$(fname)&location=$(x:location)&price=$(x:price)";//policy.CallBackUrl = "http://ip/url";string upToken = policy.Token();PutExtra extra = new PutExtra(); //扩展属性Dictionary<string,string> dict =new Dictionary<string,string>();dict.Add("x:extra", "location=shanghai&age=28");dict.Add("x:callbackUrl", "http://127.0.0.1/callback");extra.Params = dict;IOClient client = new IOClient();return client.PutFile(upToken, key, fname, extra);}

 

 

完整源代码下载 :source code

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux下DRBD配置

一、什么是DRBD1、简介 Distributed Replicated Block Device(DRBD)是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。数据镜像&#xff1a;实时、透明、同步&#xff08;所有服务器都成功后返回&#xff09;、异步&#xff08;本地服务器成功后返回…

vue3实现本地开发使用的px转换成vw,px转换成rem方法整理

前言&#xff1a; 项目中如果想本地开发使用px&#xff0c;但是界面上线以后界面是自适应的效果,可以有多种方式来实现效果。 一、px转成vw 1、安装&#xff0c;安装成功后&#xff0c;node_modules 会新增这两个插件包 npm i postcss-px-to-viewport-8-plugin 2、新增 post…

airplay2协议是什么_什么是AirPlay?

airplay2协议是什么AirPlay (AirPlay) AirPlay is released by Apple in the year 2004. It allows the easy exchange of audios without the use of any wired technique between the two devices. It was previously termed as AirTunes and later got its name changed to …

微信支付开发(5) 订单查询

本文介绍微信支付中订单查询功能的实现。 作者&#xff1a;方倍工作室 地址&#xff1a;http://www.cnblogs.com/txw1958/p/wxpay-order-query.html 一、订单查询 因为某一方技术的原因&#xff0c;可能导致商户在预期时间内都收不到最终支付通知&#xff0c;此时商户可以通过该…

python饼形图_Python | 饼形图

python饼形图A pie plot or a pie chart is a circular statistical graphic technique, in which a circle is divided into slices with respect to numerical proportion. In a pie chart, the arc length, central angle, and area of each slice, is proportional to the …

appweb ejs_EJS部分

appweb ejsHi! Welcome. Today, we are going to look at EJS partials. EJS Partials help us avoid repetition of the same code on several web pages. 嗨&#xff01; 欢迎。 今天&#xff0c;我们将看EJS局​​部函数 。 EJS Partials帮助我们避免在多个网页上重复相同的…

同事反馈环:如何实现持续改进的文化

“魔镜魔镜告诉我&#xff0c;谁才是最美丽的人&#xff1f;”&#xff0c;邪恶的皇后如此问道。似乎在精益和敏捷企业中也会有很多与《白雪公主》中类似的问题&#xff0c;如果我们没有一面可以看到我们正在做什么的镜子&#xff0c;我们就很难搞清楚我们有多么美丽&#xff0…

经典功率谱估计及Matlab仿真

原文出自&#xff1a;http://www.cnblogs.com/jacklu/p/5140913.html 功率谱估计在分析平稳各态遍历随机信号频率成分领域被广泛使用&#xff0c;并且已被成功应用到雷达信号处理、故障诊断等实际工程中。本文给出了经典功率谱估计的几类方法&#xff0c;并通过Matlab的实验仿真…

极验验证码流程-3.图片加密处理 图片移位

终于把图片加密给搞定了&#xff0c;原理是他把图分成了52个部分&#xff0c;然后通过移动来形成新的图片 主要的位置关系看代码 顺便吐槽下ruby,小众语言就是这么不方便&#xff0c;很多库都没有&#xff0c;百度了半天 最后换成了java来写 图片保存到本地的就不详细说了 主要…

html-iframe_HTML iframe

html-iframeiframe (Iframes) In HTML, iframes are used to display a webpage inside another webpage. 在HTML中&#xff0c; iframe用于在另一个网页内显示一个网页。 Syntax: 句法&#xff1a; <iframe src"URL"></iframe>The <iframe> tag…

集合操作(三)Set

2019独角兽企业重金招聘Python工程师标准>>> Set集合 HashSet 哈希表保证元素的唯一性依赖于两个方法一个是hashCode方法一个是equals方法 如果两个对象的hashCode值相同,并且调用该对象的equals方法返回的是true的时候,那么就说明两个对象是相同的 结论&#xff1a…

第6周 搜索与排序

1 查找里程 给你这样一张里程表&#xff0c;如何写一个程序&#xff0c;输入两地的地名&#xff0c;能输出期间的里程&#xff1f; #include <stdio.h> #include <string.h> #define C_LEN 30typedef struct city {char name1[C_LEN];char name2[C_LEN];int distan…

(转) Twisted :第十九部分 改变之前的想法

2019独角兽企业重金招聘Python工程师标准>>> 简介 Twisted是一个正在进展的项目,它的开发者会定期添加新的特性并且扩展旧的特性. 随着Twisted 10.1.0发布,开发者向 Deferred 类添加了一个新的特性—— cancellation ——这正是我们今天要研究的. 异步编程将请求和响…

Mac 获取 Brew

2019独角兽企业重金招聘Python工程师标准>>> 终端输入 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 转载于:https://my.oschina.net/fdstudio/blog/610680

express 项目生成器_用于项目的Express模板生成器(2)| 应用程序结构研究

express 项目生成器Hello! In express template generator for your projects (1), we looked at express generator and how we can start an express application with stressing to build a brand new structure of all required files. 你好&#xff01; 在针对您的项目的E…

Linux 服务器中文乱码编码解决

Linux环境的ECS中&#xff0c;若出现如下中文显示为乱码的情况。 一般原因如下: 1. 未安装中文语言包 2. 未设置正确的默认语言 3. SSH 终端未正确配置 本文以Centos 6.5为例&#xff0c;演示如何解决中文乱码问题。 1. 使用 locale -a |grep zh_CN查看系统是否已经安装…

ldo regula_使用C中的Regula Falsi方法找到复多项式方程的根

ldo regulaRegula Falsi方法 (Regula Falsi method) About the method: 关于方法&#xff1a; We often hear many children and even many adults complaining about the difficulty level that they face while solving complex polynomial equations. It is also difficult…

go newscanner判断文件读取结束_Go单元测试-testing

在开发程序中&#xff0c;很重要一点就是测试&#xff0c;测试可以保证代码的质量&#xff0c;保证每个函数可以正常运行。但是如何保证写出来的程序是否正确。单元测试一般是用来测试我们的代码逻辑有没有问题&#xff0c;有没有按照我们期望的运行&#xff0c;以保证代码质量…

nextdate函数白盒测试问题 软件测试_软件测试基本常识

一、软件测试的分类&#xff1a;1.按照是否执行被测试软件来分&#xff1a;静态测试&#xff1a;是指不运行软件&#xff0c;测试包括代码检查、静态结构分析、代码质量度量等&#xff0c;主要对软件需求说明书、设计说明书、软件源代码进行检查与分析。 动态测试&#xff1a;…

ideatomcat老是运行以前的项目_日“吞”150吨垃圾,禅城集中式餐厨垃圾处理项目启用...

12月9日&#xff0c;禅城区集中式餐厨垃圾处理项目正式投料试运行&#xff0c;该项目如今每天可处理150吨垃圾。这意味着禅城区将通过先进技术实现餐厨垃圾资源化、减量化、无害化处理。禅城区集中式餐厨垃圾处理项目位于佛山市南庄污水处理厂首期工程北侧&#xff0c;禅港路西…