Response.WriteFile 无法下载大文件解决方法

以前用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 = 204800;

            //建立一个200K的缓冲区

            byte[] buffer = new byte[chunkSize];

            //已读的字节数

            long dataToRead = 0;

            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 > 0)

                {

                    if (HttpContext.Current.Response.IsClientConnected)

                    {

                        int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize));

                        HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);

                        HttpContext.Current.Response.Flush();

                        HttpContext.Current.Response.Clear();

                        dataToRead -= length;

                    }

                    else

                    {

                        //防止client失去连接

                        dataToRead = -1;

                    }

                }

            }

            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 = 204800;

            //建立一个200K的缓冲区

            byte[] buffer = new byte[chunkSize];

            //已读的字节数

            long dataToRead = 0;

            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 > 0)

                {

                    if (HttpContext.Current.Response.IsClientConnected)

                    {

                        int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize));

                        HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);

                        HttpContext.Current.Response.Flush();

                        //HttpContext.Current.Response.Clear();

                        buffer = new Byte[chunkSize];

                        dataToRead = dataToRead - length;

                    }

                    else

                    {

                        //防止client失去连接

                        dataToRead = -1;

                    }

                }

            }

            catch (Exception ex)

            {

                throw ex;

                //HttpContext.Current.Response.Write("Error:" + ex.Message);

            }

            finally

            {

                if (stream != null)

                {

                    stream.Close();

                }

                HttpContext.Current.Response.Close();

            }

        }

    }

 

你可能感兴趣的:(response)