看下面的处理程序:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- namespace FileExplorer
- {
- /// <summary>
- /// Summary description for HandlerForMyFE
- /// </summary>
- public class HandlerForMyFE : IHttpHandler,System.Web.SessionState.IRequiresSessionState
- {
- private HttpContext _context;
- private HttpContext Context
- {
- get
- {
- return _context;
- }
- set
- {
- _context = value;
- }
- }
- public void ProcessRequest(HttpContext context)
- {
- Context = context;
- string filePath = context.Request.QueryString["Downloadpath"];
- filePath = context.Server.MapPath(filePath);
- if (filePath == null)
- {
- return;
- }
- System.IO.StreamReader streamReader = new System.IO.StreamReader(filePath);
- System.IO.BinaryReader br = new System.IO.BinaryReader(streamReader.BaseStream);
- byte[] bytes = new byte[streamReader.BaseStream.Length];
- br.Read(bytes,(int)streamReader.BaseStream.Length);
- if (bytes == null)
- {
- return;
- }
- streamReader.Close();
- br.Close();
- string fileName = System.IO.Path.GetFileName(filePath);
- string MimeType = GetMimeType(fileName);
- string extension = System.IO.Path.GetExtension(filePath);
- char[] extension_ar = extension.tocharArray();
- string extension_Without_dot = string.Empty;
- for (int i = 1; i < extension_ar.Length; i++)
- {
- extension_Without_dot += extension_ar[i];
- }
- //if (extension == ".jpg")
- //{ // Handle *.jpg and
- // WriteFile(bytes,fileName,"image/jpeg jpeg jpg jpe",context.Response);
- //}
- //else if (extension == ".gif")
- //{// Handle *.gif
- // WriteFile(bytes,"image/gif gif",context.Response);
- //}
- if (HttpContext.Current.Session["User_ID"] != null)
- {
- WriteFile(bytes,MimeType + " " + extension_Without_dot,context.Response);
- }
- }
- private void WriteFile(byte[] content,string fileName,string contentType,HttpResponse response)
- {
- response.Buffer = true;
- response.Clear();
- response.ContentType = contentType;
- response.AddHeader("content-disposition","attachment; filename=" + fileName);
- response.BinaryWrite(content);
- response.Flush();
- response.End();
- }
- private string GetMimeType(string fileName)
- {
- string mimeType = "application/unknown";
- string ext = System.IO.Path.GetExtension(fileName).ToLower();
- Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
- if (regKey != null && regKey.GetValue("Content Type") != null)
- mimeType = regKey.GetValue("Content Type").ToString();
- return mimeType;
- }
- public bool IsReusable
- {
- get
- {
- return false;
- }
- }
- }
- }
我使用这个处理程序下载我的文件而不直接在浏览器中打开它们 – > (使用查询字符串路径)
如何让我的文件恢复?
我在互联网下载管理器中没有这个选项!
解决方法
根据要求,这是答案的“清理”版本:
- public static bool DownloadFileMethod(HttpContext httpContext,string filePath,long speed)
- {
- // Many changes: mostly declare variables near use
- // Extracted duplicate references to HttpContext.Response and .Request
- // also duplicate reference to .HttpMethod
- // Removed try/catch blocks which hid any problems
- var response = httpContext.Response;
- var request = httpContext.Request;
- var method = request.HttpMethod.ToUpper();
- if (method != "GET" &&
- method != "HEAD")
- {
- response.StatusCode = 501;
- return false;
- }
- if (!File.Exists(filePath))
- {
- response.StatusCode = 404;
- return false;
- }
- // Stream implements IDisposable so should be in a using block
- using (var myFile = new FileStream(filePath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
- {
- var fileLength = myFile.Length;
- if (fileLength > Int32.MaxValue)
- {
- response.StatusCode = 413;
- return false;
- }
- var lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r");
- var fileName = Path.GetFileName(filePath);
- var fileNameUrlEncoded = HttpUtility.UrlEncode(fileName,Encoding.UTF8);
- var eTag = fileNameUrlEncoded + lastUpdateTiemStr;
- var ifRange = request.Headers["If-Range"];
- if (ifRange != null && ifRange.Replace("\"","") != eTag)
- {
- response.StatusCode = 412;
- return false;
- }
- long startBytes = 0;
- // Just guessing,but I bet you want startBytes calculated before
- // using to calculate content-length
- var rangeHeader = request.Headers["Range"];
- if (rangeHeader != null)
- {
- response.StatusCode = 206;
- var range = rangeHeader.Split(new[] {'=','-'});
- startBytes = Convert.ToInt64(range[1]);
- if (startBytes < 0 || startBytes >= fileLength)
- {
- // TODO: Find correct status code
- response.StatusCode = (int) HttpStatusCode.BadRequest;
- response.StatusDescription =
- string.Format("Invalid start of range: {0}",startBytes);
- return false;
- }
- }
- response.Clear();
- response.Buffer = false;
- response.AddHeader("Content-MD5",GetMD5Hash(filePath));
- response.AddHeader("Accept-Ranges","bytes");
- response.AppendHeader("ETag",string.Format("\"{0}\"",eTag));
- response.AppendHeader("Last-Modified",lastUpdateTiemStr);
- response.ContentType = "application/octet-stream";
- response.AddHeader("Content-Disposition","attachment;filename=" +
- fileNameUrlEncoded.Replace("+","%20"));
- var remaining = fileLength - startBytes;
- response.AddHeader("Content-Length",remaining.ToString());
- response.AddHeader("Connection","Keep-Alive");
- response.ContentEncoding = Encoding.UTF8;
- if (startBytes > 0)
- {
- response.AddHeader("Content-Range",string.Format(" bytes {0}-{1}/{2}",startBytes,fileLength - 1,fileLength));
- }
- // BinaryReader implements IDisposable so should be in a using block
- using (var br = new BinaryReader(myFile))
- {
- br.BaseStream.Seek(startBytes,SeekOrigin.Begin);
- const int packSize = 1024*10; //read in block,every block 10K bytes
- var maxCount = (int) Math.Ceiling((remaining + 0.0)/packSize); //download in block
- for (var i = 0; i < maxCount && response.IsClientConnected; i++)
- {
- response.BinaryWrite(br.ReadBytes(packSize));
- response.Flush();
- // HACK: Unexplained sleep
- var sleep = (int) Math.Ceiling(1000.0*packSize/speed); //the number of millisecond
- if (sleep > 1) Thread.Sleep(sleep);
- }
- }
- }
- return true;
- }