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();
                }
            }
        }
  • 相关阅读:
    中国石油昆仑加油卡
    157 01 Android 零基础入门 03 Java常用工具类01 Java异常 01 异常介绍 02 异常内容简介
    156 01 Android 零基础入门 03 Java常用工具类01 Java异常 01 异常介绍 01 Java常用工具类简介
    155 01 Android 零基础入门 02 Java面向对象 07 Java多态 07 多态知识总结 01 多态总结
    154 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 05 匿名内部类
    153 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 04 方法内部类
    152 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 03 静态内部类
    151 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 02 成员内部类
    150 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类概述 01 内部类概述
    149 01 Android 零基础入门 02 Java面向对象 07 Java多态 05 接口(重点)07 接口的继承
  • 原文地址:https://www.cnblogs.com/hulang/p/2934640.html
Copyright © 2011-2022 走看看