zoukankan      html  css  js  c++  java
  • 转(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();
                }
            }

        } 

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

  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/abcdwxc/p/3918841.html
Copyright © 2011-2022 走看看