以前用Response.WriteFile(filename),但当遇到大文件时无法完整下载。

该方法最大的问题,它不是直接将数据抛到客户端,而是在服务器端(IIS)上缓存。当下载文件比较大时,服务器压力会很大,iis虽然支持2G大小的文件下载,但当文件上了很多M时,由于服务器以及网络等因素的影响,异常概率相当大。所以当需要下载大文件时就不能使用上面的方法了。

微软推荐以下方法代替之:

■将数据分成较小的部分,然后将其移动到输出流以供下载,从而获取这些数据。
■为用户提供用于下载文件的链接。 
■使用 Microsoft ASP 3.0 进行下载或者与 ASP 一起使用 Software Artisans FileUp。 
■创建 ISAPI 扩展以下载文件。 
■使用 FTP 下载文件。
参考文档:http://support.microsoft.com/default.aspx?scid=kb;zh-cn;812406

C#相关代码如下:

public class FileDown
    {
        public FileDown()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
        /// <summary>
        /// 参数为虚拟路径
        /// </summary>
        /// <param name="FileName"></param>
        /// <returns></returns>
        public static string FileNameExtension(string FileName)
        {
            return Path.GetExtension(MapPathFile(FileName));
        }
        /// <summary>
        /// 获取物理地址
        /// </summary>
        /// <param name="FileName"></param>
        /// <returns></returns>
        public static string MapPathFile(string FileName)
        {
            return HttpContext.Current.Server.MapPath(FileName);
        }
        /// <summary>
        ///使用WriteFile下载文件,参数为文件虚拟路径
        /// </summary>
        /// <param name="FileName"></param>
        public static void DownLoadold(string FileName)
        {
            string destFileName = MapPathFile(FileName);
            // Labelmsg.Text = destFileName;
            if (File.Exists(destFileName))
            {
                FileInfo fi = new FileInfo(destFileName);
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ClearHeaders();
                HttpContext.Current.Response.Buffer = false;
                //HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" +HttpUtility.UrlEncode(Path.GetFileName(destFileName),System.Text.Encoding.Default));
                HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(destFileName), System.Text.Encoding.UTF8));
                HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString());
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.WriteFile(destFileName);
                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.End();
            }
        }
        /// <summary>
        /// 使用OutputStream.Write分块下载文件,参数为文件虚拟路径
        /// </summary>
        /// <param name="FileName"></param>
        public static void DownLoad(string FileName)
        {
            string filePath = MapPathFile(FileName);
            //指定块大小
            long chunkSize = ;
            //建立一个200K的缓冲区
            byte[] buffer = new byte[chunkSize];
            //已读的字节数
            long dataToRead = ;
            FileStream stream = null;
            try
            {
                //打开文件
                stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                dataToRead = stream.Length;
                //添加Http头
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + HttpUtility.UrlEncode(Path.GetFileName(filePath)));
                HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());
                while (dataToRead > )
                {
                    if (HttpContext.Current.Response.IsClientConnected)
                    {
                        int length = stream.Read(buffer, , Convert.ToInt32(chunkSize));
                        HttpContext.Current.Response.OutputStream.Write(buffer, , length);
                        HttpContext.Current.Response.Flush();
                        HttpContext.Current.Response.Clear();
                        dataToRead -= length;
                    }
                    else
                    {
                        //防止client失去连接
                        dataToRead = -;
                    }
                }
            }
            catch (Exception ex)
            {
                HttpContext.Current.Response.Write("Error:" + ex.Message);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
                HttpContext.Current.Response.Close();
            }
        }         /// <summary>
        /// 使用OutputStream.Write分块下载文件,参数为文件绝对路径
        /// </summary>
        /// <param name="FileName"></param>
        public static void DownLoadFile(string filePath)
        {
            //string filePath = MapPathFile(FileName);
            //指定块大小
            long chunkSize = ;
            //建立一个200K的缓冲区
            byte[] buffer = new byte[chunkSize];
            //已读的字节数
            long dataToRead = ;
            FileStream stream = null;
            try
            {
                //打开文件
                stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                dataToRead = stream.Length;
                //添加Http头
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + HttpUtility.UrlEncode(Path.GetFileName(filePath)));
                HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());
                while (dataToRead > )
                {
                    if (HttpContext.Current.Response.IsClientConnected)
                    {
                        int length = stream.Read(buffer, , Convert.ToInt32(chunkSize));
                        HttpContext.Current.Response.OutputStream.Write(buffer, , length);
                        HttpContext.Current.Response.Flush();
                        //HttpContext.Current.Response.Clear();
                        buffer = new Byte[chunkSize];
                        dataToRead = dataToRead - length;
                    }
                    else
                    {
                        //防止client失去连接
                        dataToRead = -;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
                //HttpContext.Current.Response.Write("Error:" + ex.Message);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
                HttpContext.Current.Response.Close();
            }
        }

}

转载于 http://www.cnblogs.com/hulang/archive/2013/02/27/2934640.html

转(Response.WriteFile 无法下载大文件解决方法)的更多相关文章

  1. IIS设置允许下载.exe文件解决方法(转)

    最近很多客户使用IIS服务器,然后提示返现宝下载无法找到等无法下载的问题. 返现宝是.exe安装文件,部分服务器或主机可能无法下载. 第一.如果是自己服务器或VPS请按如下设置: 1.设置MIME,让 ...

  2. IIS设置允许下载.exe文件解决方法

    最近很多客户使用IIS服务器,然后提示返现宝下载无法找到等无法下载的问题. 返现宝是.exe安装文件,部分服务器或主机可能无法下载. 第一.如果是自己服务器或VPS请按如下设置: 1.设置MIME,让 ...

  3. Android 开发工具类 27_多线程下载大文件

    多线程下载大文件时序图 FileDownloader.java package com.wangjialin.internet.service.downloader; import java.io.F ...

  4. 利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码

    利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码 2014-07-31 12:53 1047人阅读 评论(0) 收藏  ...

  5. python下载大文件

    1. wget def download_big_file_with_wget(url, target_file_name): """ 使用wget下载大文件 Note: ...

  6. ASP.Net 下载大文件的实现

    当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃.可以参考如下代码来避免这个问题. 关于此代码的几点说明: 1. 将数据分成较小的部分,然后将其移 ...

  7. ASP.NET Core下载大文件的实现

    当我们的ASP.NET Core网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃.可以参考如下代码来避免这个问题. 关于此代码的几点说明: 将数据分成较小 ...

  8. [libcurl]_[0基础]_[使用libcurl下载大文件]

    场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...

  9. ASP.Net 下载大文件的实现 (转)

    原文:http://www.cnblogs.com/luisliu/p/4253815.html 当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃 ...

随机推荐

  1. 通过gradle来导入jar包

    1.通过gradle配置第三方jar包 我们看到,每个module都有一个build.gradle文件,它其实是对应module的配置文件.关于build.gradle文件中具体内容的含义,我们将在最 ...

  2. Java和C++的虚函数的异同

    参考博客:点我 要点:Java中的普通函数默认为虚函数,因此动态绑定的行为是默认的,而C++必须将方法声明为虚函数(virtual关键字),执行时才会进行动态绑定,详细区别可参考代码以及注释. 代码大 ...

  3. Linear Algebra lecture4 note

    Inverse of AB,A^(A的转置) Product of elimination matrices  A=LU (no row exchanges)   Inverse of AB,A^(A ...

  4. clang编译器简介

    本文部分内容引用: 中文维基百科. 结构化编译器前端--clang介绍. 什么是clang编译器? clang是LLVM编译器工具集的一个用于编译C.C++.Objective-C的前端.LLVM项目 ...

  5. WP8应用上传失败查错

    开发的一个应用,好久没有更新. 最近做了些修改,在设备上安装测试,没什么 问题,上传到STORE,收到反馈说有两个操作必挂. 知道了直接设备安装测试和从STORE上下载,会有些不同. http://s ...

  6. mysql学习之触发器

    在借阅表和读者表当中存在着这样的关系,如果在借阅表当中添加一条数据,读者表当中对应的累计借书字段就自增1,如果在借阅表当中删除一条数据,读者表当中对应的累计借书字段就自减1,实现本功能的方法如下. 1 ...

  7. rabbitmq 重复ACK导致消息丢失

    rabbitmq 重复确认导致消息丢失 背景 rabbitmq 在应用场景中,大多采用工作队列 work-queue的模式. 在一个常见的工作队列模式中,消费者 worker 将不断的轮询从队列中拉取 ...

  8. [原]php远程odbc连接sqlsvr数据库,自定义端口,命名实例的连接方式

    远程odbc连接sqlsvr数据库,自定义端口,命名实例的连接方式,默认如果不修改的话sqlsvr的端口号是1433,默认实例名就是机器名,,如果既用了命名实例,又改了默认端口,改怎么连接数据库呢? ...

  9. javaweb页面上展示动态图片

    HTML <img alt="点击设定" name="CONSTRUCTIONPLANHIS_IMAGE_curr_img_0" src="vi ...

  10. IOS开发之网络编程开源类 Reachability应用

    先看Reachability.h发现 #import <Foundation/Foundation.h> #import <SystemConfiguration/SystemCon ...