欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOCX文档下载  

    net文件下载所有方法.docx

    • 资源ID:3061873       资源大小:42.91KB        全文页数:16页
    • 资源格式: DOCX        下载积分:6.99金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要6.99金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    net文件下载所有方法.docx

    net文件下载所有方法 URL方式直接下载,优点是:占用服务器资源少,速度快;缺点是: 不能准确计量下载次数,无法防止盗链,保存在数据库中的文件无法下载,常见格式的文件如.html 直接在浏览器中打开,不能直接下载。 二进制数据流输出方式,优点是:准确计量下载次数、能防盗链、所有文件格式都能直接下载而不是打开、保存在数据库中等非文件数据能以文件方式下载等;缺点是占用服务器资源多。 大文件下载原理是把文件切成小段数据流下载 public partial class FileDownLoad : System.Web.UI.Page /提供下载的文件,不编码的话文件名会乱码 private string fileName = HttpContext.Current.Server.UrlEncode("规范.rar"); private string filePath = HttpContext.Current.Server.MapPath("规范.rar"); /使用TransmifFile下载文件 /* 6 微软为Response对象提供了一个新的方法TransmitFile来解决使用Response.BinaryWrite 7 下载超过400mb的文件时导致Aspnet_wp.exe进程回收而无法成功下载的问题。 8 代码如下: 9 */ protected void btnDL1_Click(object sender, EventArgs e) FileInfo info = new FileInfo(filePath); long fileSize = info.Length; Response.Clear; Response.ContentType = "application/x-zip-compressed" Response.AddHeader("Content-Disposition", "attachment;filename="+ fileName); /不指明Content-Length用Flush的话不会显示下载进度 Response.AddHeader("Content-Length", fileSize.ToString); Response.TransmitFile(filePath, 0, fileSize); /Response.TransmitFile(filename); Response.Flush; Response.Close; /使用WriteFile下载文件 protected void btnDL2_Click(object sender, EventArgs e) FileInfo info = new FileInfo(filePath); long fileSize = info.Length; Response.Clear; Response.ContentType = "application/octet-stream" Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); /指定文件大小 Response.AddHeader("Content-Length", fileSize.ToString); Response.WriteFile(filePath, 0, fileSize); Response.Flush; Response.Close; /使用OutputStream.Write分块下载文件 protected void btnDL3_Click(object sender, EventArgs e) /指定块大小 long chunkSize = 102400; /建立一个100K的缓冲区 byte buffer = new bytechunkSize; /已读的字节数 long dataToRead = 0; FileStream stream = null; try /打开文件 stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); dataToRead = stream.Length; /添加Http头 Response.ContentType = "application/octet-stream" Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); Response.AddHeader("Content-Length", dataToRead.ToString); while (dataToRead > 0) if (Response.IsClientConnected) int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize); Response.OutputStream.Write(buffer, 0, length); Response.Flush; buffer = new Byte10000; dataToRead -= length; else /防止client失去连接 dataToRead = -1; catch (Exception ex) Response.Write("Error:" + ex.Message); finally if (stream != null) stream.Close; Response.Close; /使用BinaryWrite下载文件,大文件效率不行 protected void btnDL4_Click(object sender, EventArgs e) FileStream stream = null; try /读文件,大文件一次读入会占用大量内存 stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); byte bytes = new bytestream.Length; stream.Read(bytes, 0, bytes.Length); stream.Close; /添加Http头 Response.ContentType = "application/octet-stream" Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); Response.AddHeader("Content-Length", bytes.Length.ToString); Response.BinaryWrite(bytes); Response.Flush; catch (Exception ex) Response.Write("Error:" + ex.Message); finally if (stream != null) stream.Close; Response.Close; /使用BinaryWrite分块下载文件 protected void btnDL5_Click(object sender, EventArgs e) /指定区块和缓冲区 long chunkSize = 102400; byte buffer = new bytechunkSize; FileStream stream = null; long dataToRead = 0; try stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); dataToRead = stream.Length; /添加Http头 Response.ContentType = "application/octet-stream" Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); Response.AddHeader("Content-Length", dataToRead.ToString); while (dataToRead > 0) if (Response.IsClientConnected) int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize); Response.BinaryWrite(buffer); Response.Flush; Response.Clear; dataToRead -= length; else dataToRead = -1; catch(Exception ex) Response.Write("Error:" + ex.Message); finally if (stream != null) stream.Close; Response.Close; 以上除了第四种不推荐以外,其他的都可以,但是个人感觉分块下载的要好一点。没有仔细测试,所以可能有问题。 /中文标题转换 if (browser.Contains("FIREFOX") = true) outputFileName = Path.GetFileName(photo.FilePath); else outputFileName = HttpUtility.UrlEncode(Path.GetFileName(photo.FilePath); 注意:对于中文文件名要编码才能正确显示。对于长中文文件名(UTF8编码后大于153字节的中文)即使编码了,还是有问题的,大家可以参考下面的文章。 关于中文文件下载的问题,网上的咨询和答疑已经很多,我原来处理下载的代码如下: response.setHeader("Content-Disposition", "attachment; filename=" + .URLEncoder.encode(fileName, "UTF-8"); 下载的程序里有了这句,一般在IE6的下载提示框上将正确显示文件的名字,无论是简体中文,还是日文。不过当时确实没有仔细测试文件名很长的中文文件名。先如今经过仔细测试,发现文字只要超过17个字,就不能下载了。经过好一番google和反复测试,总算对这个问题有了系统的认识,分列如下: 一. 通过我原来的方式,也就是先用URLEncoder编码,当中文文字超过17个时,IE6 无法下载文件。这是IE的bug,参见微软的知识库文章 KB816868 。原因可能是因为ie在处理 Response Header 的时候,对header的长度限制在150字节左右。而一个汉字编码成UTF-8是9个字节,那么17个字便是153个字节,所以便会报错。微软提供了一个补丁,可以从 这里 下载。这个补丁需要先安装ie6 sp1。因为我平时勤打补丁,我的IE6版本号是 6.0.2800.1106.xpsp2_xxxxx。所以我可能已经安装过了补丁,从而可以下载,但仍然出现文件名被截断的现象。微软让我们等待IE下一个service pack的发布。我今天也上网看到了好消息,迫于firefox的压力,IE7可能在年中发布。另外,Firefox 不支持这样的方式,将把编码后的%xx%xx直接作为文件名显示。 二. 我尝试使用 javamail 的MimeUtility.encode方法来编码文件名,也就是编码成 =?gb2312?B?xxxxxxxx?= 这样的形式,并从 RFC1522 中找到对应的标准支持。不过很遗憾,IE6并不支持这一个标准。我试了一下,Firefox是支持的。 三. 按网上很多人提供的解决方案:将文件名编码成ISO8859-1似乎是有效的解决方案,代码如下: response.setHeader( "Content-Disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) ); 在确保附件文件名都是简体中文字的情况下,那么这个办法确实是最有效的,不用让客户逐个的升级IE。如果台湾同胞用,把gb2312改成big5就行。但现在的系统通常都加入了国际化的支持,普遍使用UTF-8。如果文件名中又有简体中文字,又有繁体中文,还有日文。那么乱码便产生了。另外,在我的电脑上Firefox(v1.0-en)下载也是乱码。 折中考虑,我结合了一、三的方式,代码片断如下: 复制代码 代码如下: String fileName = URLEncoder.encode(atta.getFileName, "UTF-8"); /* * see */ if (fileName.length > 150) String guessCharset = xxxx /*根据request的locale 得出可能的编码,中文操作系统通常是gb2312*/ fileName = new String(atta.getFileName.getBytes(guessCharset), "ISO8859-1"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); 暂且不考虑 Firefox 是因为它目前似乎还没有有力侵食到IE的企业用户市场。影响客户买单的常常是进度,而不是兼容度。 / <summary> / 下载文件,支持大文件、续传、速度限制。支持续传的响应头Accept-Ranges、ETag,请求头Range 。 / Accept-Ranges:响应头,向客户端指明,此进程支持可恢复下载.实现后台智能传输服务,值为:bytes; / ETag:响应头,用于对客户端的初始响应,以及来自客户端的恢复请求, / 必须为每个文件提供一个唯一的ETag值,这使客户端软件能够验证它们已经下载的字节块是否仍然是最新的。 / Range:续传的起始位置,即已经下载到客户端的字节数,值如:bytes=1474560- 。 / 另外:UrlEncode编码后会把文件名中的空格转换中+,但是浏览器是不能理解加号为空格的,所以在浏览器下载得到的文件,空格就变成了加号; / 解决办法:UrlEncode 之后, 将 "+" 替换成 "%20",因为浏览器将%20转换为空格 / </summary> / <param name="httpContext">当前请求的HttpContext</param> / <param name="filePath">下载文件的物理路径,含路径、文件名</param> / <param name="speed">下载速度:每秒允许下载的字节数</param> / <returns>true下载成功,false下载失败</returns> public static bool DownloadFile(HttpContext httpContext, string filePath, long speed) bool ret = true; try /-验证:HttpMethod,请求的文件是否存在 switch (httpContext.Request.HttpMethod.ToUpper) /目前只支持GET和HEAD方法 case "GET": case "HEAD": break; default: httpContext.Response.StatusCode = 501; return false; / if (!File.Exists(filePath) / / httpContext.Response.StatusCode = 404; / return false; / /定义局部变量 long startBytes = 0; int packSize = 1024 * 10; /分块读取,每块10K bytes string fileName = Path.GetFileName(filePath); FileStream myFile = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(myFile); long fileLength = myFile.Length; int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);/毫秒数:读取下一数据块的时间间隔 string lastUpdateTiemStr = System.IO.File.GetLastWriteTimeUtc(filePath).ToString("r"); string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr;/便于恢复下载时提取请求头; / -验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修改过- if (myFile.Length > Int32.MaxValue) /-文件太大了- httpContext.Response.StatusCode = 413;/请求实体太大 return false; if (httpContext.Request.Headers"If-Range" != null)/对应响应头ETag:文件名+文件最后修改时间 /-上次被请求的日期之后被修改过- if (httpContext.Request.Headers"If-Range".Replace(""", "") != eTag) /文件修改过 httpContext.Response.StatusCode = 412;/预处理失败 return false; try / -添加重要响应头、解析请求头、相关验证- httpContext.Response.Clear; httpContext.Response.Buffer = false; /httpContext.Response.AddHeader("Content-MD5", GetMD5Hash(myFile);/用于验证文件 httpContext.Response.AddHeader("Accept-Ranges", "bytes");/重要:续传必须 httpContext.Response.AppendHeader("ETag", """ + eTag + """);/重要:续传必须 httpContext.Response.AppendHeader("Last-Modified", lastUpdateTiemStr);/把最后修改日期写入响应 httpContext.Response.ContentType = "application/octet-stream"/MIME类型:匹配任意文件类型 httpContext.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20"); httpContext.Response.AddHeader("Content-Length", (fileLength - startBytes).ToString); httpContext.Response.AddHeader("Connection", "Keep-Alive"); httpContext.Response.ContentEncoding = Encoding.UTF8; if (httpContext.Request.Headers"Range" != null) /-如果是续传请求,则获取续传的起始位置,即已经下载到客户端的字节数- httpContext.Response.StatusCode = 206;/重要:续传必须,表示局部范围响应。初始下载时默认为200 string range = httpContext.Request.Headers"Range".Split(new char '=', '-' );/"bytes=1474560-" startBytes = Convert.ToInt64(range1);/已经下载的字节数,即本次下载的开始位置 if (startBytes < 0 | startBytes >= fileLength) /无效的起始位置 return false; if (startBytes > 0) /-如果是续传请求,告诉客户端本次的开始字节数,总长度,以便客户端将续传数据追加到startBytes位置后- httpContext.Response.AddHeader("Content-Range", string.Format(" bytes 0-1/2", startBytes, fileLength - 1, fileLength); / -向客户端发送数据块- br.BaseStream.Seek(startBytes, SeekOrigin.Begin); int maxCount = (int)Math.Ceiling(fileLength - startBytes + 0.0) / packSize);/分块下载,剩余部分可分成的块数 for (int i = 0; i < maxCount && httpContext.Response.IsClientConnected; i+) /客户端中断连接,则暂停 httpContext.Response.BinaryWrite(br.ReadBytes(packSize); httpContext.Response.Flush; if (sleep > 1) System.Threading.Thread.Sleep(sleep); catch ret = false; finally br.Close; myFile.Close; catch ret = false; return ret; /* 哈希函数将任意长度的二进制字符串映射为固定长度的小型二进制字符串。加密哈希函数有这样一个属性:在计算上不大可能找到散列为相同的值的两个不同的输入;也就是说,两组数据的哈希值仅在对应的数据也匹配时才会匹配。数据的少量更改会在哈希值中产生不可预知的大量更改。 MD5 算法的哈希值大小为 128 位。 MD5 类的 ComputeHash 方法将哈希作为 16 字节的数组返回。请注意,某些 MD5 实现会生成 32 字符的十六进制格式哈希。若要与此类实现进行互操作,请将 ComputeHash 方法的返回值格式化为十六进制值。 */ / <summary> / 获取输入流的由MD5计算的Hash值,不可逆转 / <param name="inputStream"></param> / <returns></returns> public static string GetMD5Hash(Stream inputStream) / Create a new instance of the MD5CryptoServiceProvider object. MD5 md5Hasher = MD5.Create;/不可逆转 byte data = md5Hasher.ComputeHash(inputStream); StringBuilder sb = new StringBuilder; for (int i = 0; i < data.Length; i+) sb.Append(datai.ToString("x2");/十六进 / 返回十六进制的字符串 return sb.ToString; / <summary> / 验证输入流由MD5计算的Hash值 / </summary> / <param name="inputStream"></param> / <param name="hash"></param> / <returns></returns> public static bool VerifyMD5Hash(Stream inputStream, string hash) string hashOfInputStream = GetMD5Hash(inputStream); StringComparer comparer = StringComparer.OrdinalIgnoreCase; if (comparer.Compare(hashOfInputStream, hash) = 0) return true; else return false;

    注意事项

    本文(net文件下载所有方法.docx)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开