C#集成FastDFS断点续传

参考

.net版本FastDFS客户端v5.05。

https://github.com/zhouyh362329/fastdfs.client.net

FastDFS环境准备。

http://www.cnblogs.com/ddrsql/p/7118695.html

webuploader。

http://fex.baidu.com/webuploader/

普通方式下载

非断点续传方式下载。

        /// <summary>/// 普通下载/// </summary>public void Download(){string fileName = "下载测试test.txt";string filePath = Server.MapPath("/File/test.txt");System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);if (fileInfo.Exists == true){const long ChunkSize = 10240;byte[] buffer = new byte[ChunkSize];Response.Clear();System.IO.FileStream iStream = System.IO.File.OpenRead(filePath);long dataLengthToRead = iStream.Length;//获取下载的文件总大小 Response.ContentEncoding = Encoding.UTF8;Response.ContentType = "application/octet-stream";Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);while (dataLengthToRead > 0 && Response.IsClientConnected){Thread.Sleep(100);int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//读取的大小 Response.OutputStream.Write(buffer, 0, lengthRead);Response.Flush();dataLengthToRead -= lengthRead;}Response.Close();}}

下载完成前客户端不知道文件大小。

MVC FastDFS 断点续传方式下载

断点续传几个关键Header属性:

Request

If-Range、Range

Response

StatusCode = 206

Accept-Ranges、ETag、Content-Length、Content-Range

        /// <summary>/// FastDFS下载文件,断点续传/// </summary>/// <returns></returns>public bool DownloadByFDFS(){string group_name = "group1";string remote_filename = "M00/00/00/CgEG1FlWChOEHXNFAAAAAEFinIM178.txt";string fileName = "测试.txt";long length = 2878186;long speed = 1024 * 100;bool ret = true;try{#region--验证:HttpMethod,请求的文件是否存在switch (Request.HttpMethod.ToUpper()){ //目前只支持GET和HEAD方法case "GET":case "HEAD":break;default:Response.StatusCode = 501;return false;}#endregion#region 定义局部变量long startBytes = 0;int packSize = 1024 * 10; //分块读取,每块10K byteslong fileLength = length;// myFile.Length;int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);//毫秒数:读取下一数据块的时间间隔string lastUpdateTiemStr = "2017-07-18 11:57:54";string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr;//便于恢复下载时提取请求头;#endregion#region--验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修改过--------------//if (myFile.Length > Int32.MaxValue)//{//-------文件太大了-------//    Response.StatusCode = 413;//请求实体太大//    return false;//}if (Request.Headers["If-Range"] != null)//对应响应头ETag:文件名+文件最后修改时间
                {//----------上次被请求的日期之后被修改过--------------if (Request.Headers["If-Range"].Replace("\"", "") != eTag){//文件修改过Response.StatusCode = 412;//预处理失败return false;}}#endregiontry{#region -------添加重要响应头、解析请求头、相关验证-------------------Response.Clear();Response.Buffer = false;//Response.AddHeader("Content-MD5", GetMD5Hash(myFile));//用于验证文件Response.AddHeader("Accept-Ranges", "bytes");//重要:续传必须Response.AppendHeader("ETag", "\"" + eTag + "\"");//重要:续传必须Response.AppendHeader("Last-Modified", lastUpdateTiemStr);//把最后修改日期写入响应                Response.ContentType = "application/octet-stream";//MIME类型:匹配任意文件类型Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);//s HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20"));
Response.AddHeader("Connection", "Keep-Alive");Response.ContentEncoding = Encoding.UTF8;if (Request.Headers["Range"] != null){//------如果是续传请求,则获取续传的起始位置,即已经下载到客户端的字节数------Response.StatusCode = 206;//重要:续传必须,表示局部范围响应。初始下载时默认为200string[] range = Request.Headers["Range"].Split(new char[] { '=', '-' });//"bytes=1474560-"startBytes = Convert.ToInt64(range[1]);//已经下载的字节数,即本次下载的开始位置  if (startBytes < 0 || startBytes >= fileLength){//无效的起始位置return false;}}Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());if (startBytes > 0){//------如果是续传请求,告诉客户端本次的开始字节数,总长度,以便客户端将续传数据追加到startBytes位置后----------Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));}#endregion#region -------向客户端发送数据块-------------------//binaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);int maxCount = (int)Math.Ceiling((fileLength - startBytes + 0.0) / packSize);//分块下载,剩余部分可分成的块数for (int i = 0; i < maxCount && Response.IsClientConnected; i++){//客户端中断连接,则暂停if (fileLength - startBytes < packSize)packSize = 0;byte[] fdfs = client.download_file(group_name, remote_filename, startBytes, packSize);Response.BinaryWrite(fdfs);Response.Flush();startBytes = startBytes + packSize;if (sleep > 1) Thread.Sleep(sleep);}#endregion}catch{ret = false;}finally{}}catch{ret = false;}return ret;}

断点续传方式下载文件效果:

MVC FastDFS断点续传方式上传

文件分段上传至FastDFS首次使用upload_appender_file,之后使用append_file追加。

        public string Upload(HttpPostedFileBase file){string group = "";string path = "";string tempPath = Server.MapPath("~/File/temp.txt");byte[] buffer = new byte[file.ContentLength];System.IO.Stream fs = (System.IO.Stream)file.InputStream;fs.Read(buffer, 0, file.ContentLength);NameValuePair[] meta_list = new NameValuePair[4];meta_list[0] = new NameValuePair("width", "800");meta_list[1] = new NameValuePair("heigth", "600");meta_list[2] = new NameValuePair("bgcolor", "#FFFFFF");meta_list[3] = new NameValuePair("author", "Mike");if (Request.Params["chunk"] == "0" || Request.Params["chunk"] == null){string ext = Path.GetExtension(file.FileName).Replace(".", "");//fastdfs上传var results = client.upload_appender_file(buffer, ext, meta_list);group = results[0];path = results[1];//临时存储group、pathStreamWriter sw = new StreamWriter(tempPath, false);sw.WriteLine(group);sw.WriteLine(path);sw.Close();}else{if (System.IO.File.Exists(tempPath)){StreamReader sr = new StreamReader(tempPath);int i = 0;string strReadline = string.Empty;//读取group、pathwhile ((strReadline = sr.ReadLine()) != null){if (i == 0)group = strReadline;else if (i == 1)path = strReadline;i++;}sr.Close();}//文件续传,fastdfs追加上传var flag = client.append_file(group, path, buffer);}return "{\"data\":{\"chunked\" : true, \"ext\" : \"exe\"}}";}public string GetMaxChunk(string md5){//根据实际存储介质返回文件上传终止的段return "{\"data\":0}";}

上传pconline1477535934501.zip文件测试。

 

上传完成后查看/File/temp.txt文件记录。

到相应的group查看:

WEBAPI FastDFS断点续传方式下载

WEBAPI中PushStreamContent 推送

        /// <summary>/// PushStreamContent 推送/// FDFS文件,断点续传/// </summary>/// <returns></returns>public HttpResponseMessage GetFileFDFS(){HttpResponseMessage response = new HttpResponseMessage();if (Request.Headers.IfRange != null && Request.Headers.IfRange.EntityTag.ToString().Replace("\"", "") != NowTime){response.StatusCode = HttpStatusCode.PreconditionFailed;return response;}string group_name = "group1";string remote_filename = "M00/00/00/CgEG1FlWChOEHXNFAAAAAEFinIM178.txt";string fileName = "测试.txt";long fileLength = 2878186;long speed = 1024 * 100;long packSize = 1024 * 10;int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);//毫秒数:读取下一数据块的时间间隔ContentInfo contentInfo = GetContentInfoFromRequest(this.Request, fileLength);Action<Stream, HttpContent, TransportContext> pushContentAction = (outputStream, content, context) =>{try{int length = Convert.ToInt32((fileLength - 1) - contentInfo.From) + 1;while (length > 0 && packSize > 0){byte[] fdfs = client.download_file(group_name, remote_filename, contentInfo.From, Math.Min(length, packSize));outputStream.Write(fdfs, 0, fdfs.Length);contentInfo.From = contentInfo.From + fdfs.Length;length -= fdfs.Length;if (sleep > 1) Thread.Sleep(sleep);}//int maxCount = (int)Math.Ceiling((fileLength - contentInfo.From + 0.0) / packSize);//分块下载,剩余部分可分成的块数//for (int i = 0; i < maxCount && HttpContext.Current.Response.IsClientConnected; i++)//{//    if (fileLength - contentInfo.From < packSize)//        packSize = 0;//    byte[] fdfs = client.download_file(group_name, remote_filename, contentInfo.From, packSize);//    outputStream.Write(fdfs, 0, fdfs.Length);//    contentInfo.From = contentInfo.From + fdfs.Length;//    if (sleep > 1) Thread.Sleep(sleep);//}
                }catch (HttpException ex){throw ex;}finally{outputStream.Close();}};response.Content = new PushStreamContent(pushContentAction, new MediaTypeHeaderValue(MimeType));//response.Content = new PushStreamContent(pushContentAction);
            SetResponseHeaders(response, contentInfo, fileLength, fileName);return response;}

demo下载地址:https://pan.baidu.com/s/1i5rDs49

 

 

转载于:https://www.cnblogs.com/ddrsql/p/7199894.html

C#集成FastDFS断点续传相关推荐

  1. Nignx集成fastDFS后访问Nginx一直在加载中解决

    问题描述: Nginx集成fastDFS后,访问Nginx一直在加载中,得不到页面.查看Nginx的错误日志: 可以看到是fastdfs.conf的配置错误,tracker的ip没有修改: fastd ...

  2. springboot(十八):使用Spring Boot集成FastDFS

    上篇文章介绍了如何使用Spring Boot上传文件,这篇文章我们介绍如何使用Spring Boot将文件上传到分布式文件系统FastDFS中. 这个项目会在上一个项目的基础上进行构建. 1.pom包 ...

  3. (转)Spring Boot(十八):使用 Spring Boot 集成 FastDFS

    http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html 上篇文章介绍了如何使用 Spring Boot 上传文件 ...

  4. FastDfs工作笔记002---SpringBoot集成FastDfs

    JAVA技术交流QQ群:170933152 这个项目会在上一个项目的基础上进行构建. 1.pom包配置 我们使用Spring Boot最新版本1.5.9.jdk使用1.8.tomcat8.0. < ...

  5. SpringBoot集成FastDFS

    FastDFS是一款高性能的分布式文件系统.主要功能包括:文件存储,文件同步,文件访问(上传下载).它可以解决高容量和负载均衡的问题.FastDFS适合用来做文件相关的网站,如图片分享.视频分享等. ...

  6. SpringBoot集成FastDFS依赖实现文件上传

    前言 对FastDFS文件系统安装后的使用. FastDFS的安装请参考这篇:https://www.cnblogs.com/niceyoo/p/13511082.html 本文环境:IDEA + J ...

  7. fastdfs删除过期文件_Spring Boot 系列:使用 Spring Boot 集成 FastDFS

    这篇文章我们介绍如何使用 Spring Boot 将文件上传到分布式文件系统 FastDFS 中. 这个项目会在上一个项目的基础上进行构建. 1.pom 包配置 org.csource fastdfs ...

  8. SpringBoot集成FastDFS的配合

    最近做的项目需要把相关的录音文件上传到FastDFS服务器,因为之前没有做过,所以都是在网上找一些资源做参考,最后经过调试,终于可以上传成功了,接下来我来和大家分享我写的相关代码,其他就不讲解了,希望 ...

  9. Nginx集成FastDFS模块实现图片上传

    提示:如果在这里还没有安装Fastdfs的话可以参考:censtos下安装FastDFS 一.FastDFS的Nginx模块 资料: https://pan.baidu.com/s/14YQCvuMI ...

  10. fastdfs上传文件_SpringBoot+FastDFS搭建分布式文件系统

    1.pom包配置 我们使用Spring Boot最新版本1.5.9.jdk使用1.8.tomcat8.0. org.csource fastdfs-client-java 1.27-SNAPSHOT ...

最新文章

  1. java 工厂 单例_java 单例模式和工厂模式实例详解
  2. 2011 ScrumGathering敏捷个人.pptx
  3. 前端,我为什么不要你(转)
  4. C#中读写INI文件
  5. 转载自《读者》--您也吻我一下好吗
  6. 【Antlr】Antlr将词法符号送入不同的通道
  7. self_number
  8. JAVA-Servlet操纵方法
  9. JavaSE思维导图
  10. 京东万能转链API接口 含商品信息优惠券转链 京东线报如何转链?
  11. 【工具】pt-online-schema-change
  12. 微信小程序tabBar的开发设置
  13. golang 单元测试进阶篇
  14. 秒杀活动(应对大并发:如何利用缓存+异步 )
  15. CSS单位px、em、rem及它们之间的换算关系
  16. 狗跳高案例和学生老师案例(继承,抽象类,接口)
  17. 多元线性回归matlab实现
  18. mysql高级 tigger触发器 --[3]
  19. 重新整理秋招准备的思路-9.20
  20. 2018codeM美团初赛B轮 4.神奇盘子

热门文章

  1. 找零钱问题系列之记忆搜索
  2. win10 tensorflow 和numpy兼容性问题 No module named ‘numpy.core._multiarray_umath‘
  3. 2020 快手 被吊打面经
  4. 服务器设置客户端网页安装,在Windows 7环境下安装并配置web、SSH、E-mail、FTP等服务器...
  5. Mysql数据恢复有哪几种_MYSQL 数据恢复有哪些
  6. 借助Haproxy_exporter实现对MarathonLb的流量和负载实例业务的可用状态监控-续
  7. 关于SVM参数cg选取的总结帖[matlab-libsvm]
  8. 词向量(从one-hot到word2vec)
  9. 计算机图形学完整笔记(三):裁剪
  10. mysql.5.7 declare_MySQL-5.7 游标及DECLARE