FileDown.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System;
  2. using System.IO;
  3. using System.Threading;
  4. using System.Web;
  5. namespace Ant.Service.Utilities
  6. {
  7. /// <summary>
  8. /// 文件下载类
  9. /// </summary>
  10. public class FileDown
  11. {
  12. public FileDown()
  13. { }
  14. /// <summary>
  15. /// 参数为虚拟路径
  16. /// </summary>
  17. public static string FileNameExtension(string FileName)
  18. {
  19. return Path.GetExtension(MapPathFile(FileName));
  20. }
  21. /// <summary>
  22. /// 获取物理地址
  23. /// </summary>
  24. public static string MapPathFile(string FileName)
  25. {
  26. return HttpContext.Current.Server.MapPath(FileName);
  27. }
  28. /// <summary>
  29. /// 普通下载
  30. /// </summary>
  31. /// <param name="FileName">文件虚拟路径</param>
  32. public static void DownLoadold(string FileName)
  33. {
  34. string destFileName = MapPathFile(FileName);
  35. if (File.Exists(destFileName))
  36. {
  37. FileInfo fi = new FileInfo(destFileName);
  38. HttpContext.Current.Response.Clear();
  39. HttpContext.Current.Response.ClearHeaders();
  40. HttpContext.Current.Response.Buffer = false;
  41. HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(destFileName), System.Text.Encoding.UTF8));
  42. HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString());
  43. HttpContext.Current.Response.ContentType = "application/octet-stream";
  44. HttpContext.Current.Response.WriteFile(destFileName);
  45. HttpContext.Current.Response.Flush();
  46. HttpContext.Current.Response.End();
  47. }
  48. }
  49. /// <summary>
  50. /// 分块下载
  51. /// </summary>
  52. /// <param name="FileName">文件虚拟路径</param>
  53. public static void DownLoad(string FileName)
  54. {
  55. string filePath = MapPathFile(FileName);
  56. long chunkSize = 204800; //指定块大小
  57. byte[] buffer = new byte[chunkSize]; //建立一个200K的缓冲区
  58. long dataToRead = 0; //已读的字节数
  59. FileStream stream = null;
  60. try
  61. {
  62. //打开文件
  63. stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
  64. dataToRead = stream.Length;
  65. //添加Http头
  66. HttpContext.Current.Response.ContentType = "application/octet-stream";
  67. HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + HttpUtility.UrlEncode(Path.GetFileName(filePath)));
  68. HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());
  69. while (dataToRead > 0)
  70. {
  71. if (HttpContext.Current.Response.IsClientConnected)
  72. {
  73. int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize));
  74. HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);
  75. HttpContext.Current.Response.Flush();
  76. HttpContext.Current.Response.Clear();
  77. dataToRead -= length;
  78. }
  79. else
  80. {
  81. dataToRead = -1; //防止client失去连接
  82. }
  83. }
  84. }
  85. catch (Exception ex)
  86. {
  87. HttpContext.Current.Response.Write("Error:" + ex.Message);
  88. }
  89. finally
  90. {
  91. if (stream != null) stream.Close();
  92. HttpContext.Current.Response.Close();
  93. }
  94. }
  95. /// <summary>
  96. /// 输出硬盘文件,提供下载 支持大文件、续传、速度限制、资源占用小
  97. /// </summary>
  98. /// <param name="_Request">Page.Request对象</param>
  99. /// <param name="_Response">Page.Response对象</param>
  100. /// <param name="_fileName">下载文件名</param>
  101. /// <param name="_fullPath">带文件名下载路径</param>
  102. /// <param name="_speed">每秒允许下载的字节数</param>
  103. /// <returns>返回是否成功</returns>
  104. //---------------------------------------------------------------------
  105. //调用:
  106. // string FullPath=Server.MapPath("count.txt");
  107. // ResponseFile(this.Request,this.Response,"count.txt",FullPath,100);
  108. //---------------------------------------------------------------------
  109. public static bool ResponseFile(HttpRequest _Request, HttpResponse _Response, string _fileName, string _fullPath, long _speed)
  110. {
  111. try
  112. {
  113. FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  114. BinaryReader br = new BinaryReader(myFile);
  115. try
  116. {
  117. _Response.AddHeader("Accept-Ranges", "bytes");
  118. _Response.Buffer = false;
  119. long fileLength = myFile.Length;
  120. long startBytes = 0;
  121. int pack = 10240; //10K bytes
  122. int sleep = (int)Math.Floor((double)(1000 * pack / _speed)) + 1;
  123. if (_Request.Headers["Range"] != null)
  124. {
  125. _Response.StatusCode = 206;
  126. string[] range = _Request.Headers["Range"].Split(new char[] { '=', '-' });
  127. startBytes = Convert.ToInt64(range[1]);
  128. }
  129. _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
  130. if (startBytes != 0)
  131. {
  132. _Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
  133. }
  134. _Response.AddHeader("Connection", "Keep-Alive");
  135. _Response.ContentType = "application/octet-stream";
  136. _Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));
  137. br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
  138. int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;
  139. for (int i = 0; i < maxCount; i++)
  140. {
  141. if (_Response.IsClientConnected)
  142. {
  143. _Response.BinaryWrite(br.ReadBytes(pack));
  144. Thread.Sleep(sleep);
  145. }
  146. else
  147. {
  148. i = maxCount;
  149. }
  150. }
  151. }
  152. catch
  153. {
  154. return false;
  155. }
  156. finally
  157. {
  158. br.Close();
  159. myFile.Close();
  160. }
  161. }
  162. catch
  163. {
  164. return false;
  165. }
  166. return true;
  167. }
  168. }
  169. }