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();
            }
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM