ashx实现文件下载以及文件MD5码测试
cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using System.Security.Cryptography; using System.Text; namespace WebApplication1.handle { /// <summary> /// serverDownLoad 的摘要说明 /// </summary> public class serverDownLoad : IHttpHandler { public void ProcessRequest(HttpContext context) { string id = context.Request.Params["Id"].ToString(); string name = context.Request.Params["name"].ToString(); Console.WriteLine(id); Console.WriteLine(name); using (FileStream fsRead = new FileStream(@"D:\1.xlsx", FileMode.Open)) { //文件读入byte数组中 int fsLen = (int)fsRead.Length; byte[] heByte = new byte[fsLen]; int r = fsRead.Read(heByte, 0, heByte.Length); //byte数组生成文件的MD5码 { MD5 md5 = new MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(heByte); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } string fileMD5 = sb.ToString(); } fsRead.Close();//此代码是用using来定义的FileStream,所以可以忽略此行代码 //文件下载 context.Response.Buffer = true; context.Response.Clear(); context.Response.ContentType = "application/octet-stream"; //fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);文件名是中文时就用这个防止乱码 context.Response.AddHeader("content-disposition", "attachment;filename=1.xlsx"); context.Response.BinaryWrite(heByte); context.Response.Flush(); context.Response.End(); } } public bool IsReusable { get { return false; } } } }
用using定义的FileStream会在using代码段执行结束之后执行FileStream的Dispose方法释放资源,而FileStream的Close方法也是调用Dispose释放资源,所以不用再次写Close方法
用using定义的类的对象需要类实现IDisposable接口,此接口提供了Dispose 方法,
PS:SqlConnection 的Close方法是指关闭连接,没有调用Dispose方法销毁对象,所以还可以通过Open方法来重新连接,但是使用using定义的时候或者自己调用Dispose方法的时候会销毁对象
其中sb.Append(retVal[i].ToString("x2"))的“x2”是一个string.Format,用来将转换成的字符串格式化的,“x2”是转换成16进制的字符串,而且每次都是两位
例如两个数10和26,正常情况十六进制显示0xA、0x1A,这样看起来不整齐,为了好看,我们可以指定X2,这样显示出来就是:0x0A、0x1A。
其他格式请看http://www.cnblogs.com/fuhai/p/5123593.html
使用的时候直接在a标签的href中指向该ashx就可以了,也可以用javascript来实现,href后面添加?ParamsName1=ParamsValue1&ParamsName2=ParamsValue2来实现传参
1 window.location.href = "handle/serverDownLoad.ashx/DownLoad?Id=123&name=fuhai";
获取参数的时候用context.Request.Params[ParamsName]获取
当读取txt文件的时候可以将文件转换成字符串(目前测试只有txt文件有效)
1 //byte数组转换成字符串,读取txt文件时有效 2 heByte = System.Text.Encoding.Convert(System.Text.Encoding.GetEncoding("gb2312"), System.Text.Encoding.UTF8, heByte); 3 string myStr = System.Text.Encoding.UTF8.GetString(heByte); 4 string myStr1 = System.Text.Encoding.Unicode.GetString(heByte); 5 Console.WriteLine(myStr);
MD5码是同来识别相同文件的,相同的文件MD5码是相同的,即便命名不一样,下面是一组MD5码的测试数据
文件txt
测试数据 111111111 22222222 22222222 3333333333 444
测试结果
文件:1.txt MD5码:057f9a55128fcd5448fdef8e56122125 文件:改名 10.txt MD5码:057f9a55128fcd5448fdef8e56122125 文件:修改后缀10.xlsx MD5码:057f9a55128fcd5448fdef8e56122125 文件:压缩 MD5码:4b27cc178681336f52bef782d30187ae 文件:第二次压缩 MD5码:4b27cc178681336f52bef782d30187ae 文件:加密压缩 密码123 MD5码:311a42b3946fc8c36cf7df59f10fd5f0 文件:第二次加密压缩 密码123456 MD5码:c097d1a3e69a64d402102d9740294532
由此可见,一个相同的文件,即便你更改了文件名和后缀,文件大的MD5码还是相同的,经过压缩后,MD5码会改变,加密压缩时,密码不同,MD5码也不同
顺便说一句,百度云盘的极速上传就是用MD5码校验的,当你上传一个文件的时候,会在服务器中查找是否有相同MD5码的文件,如果有,那就不同直接从本地上传到服务器,而是直接让你的账号指向该服务器的文件,实现秒速上传(其实根本没有上传),当然,如果服务器的文件因被举报而被限制下载,那么拥有该文件的所有用户都不能下载该文件了,所以,如果有什么重要的文件,可以加密压缩再上传到服务器,虽然上传有点慢,但是上传后,你将是服务器上该文件的唯一使用者,不用担心因被举报而被限制下载(当然前提是不分享出去),所以大家都懂的。