1. 程式人生 > >C#實現文件下載的幾種方式

C#實現文件下載的幾種方式

服務器 內存溢出 url .config smi encode public button length

上篇博客也說了下C#中通過XML導出Excel,這些文件操作都挺有用的,下面是文件的下載,之前做項目都是把它寫的空間日誌中,以後有時間了把它們都弄出來

先把有問題的代碼貼出來吧

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;

namespace infoPlatClient.NetDisk
{
    public partial class downLoad : Com.DRPENG.Common.WebStruct.BaseForm
    {

        /// <summary>
        /// 取得要下載文件的路徑
        /// </summary>
        private string fileRpath
        {
            get
            {
                return Request["fileRpath"] == null ? "" : Request["fileRpath"];
            }
        }
        /// <summary>
        /// 取得要下載文件的名稱
        /// </summary>
       
        protected void Page_Load(object sender, EventArgs e)
        {
                if (!IsPostBack)
                this.DownloadFile();
        }
        public void DownloadFile()
        {

                Response.ClearHeaders();
                Response.Clear();
                Response.Expires = 0;
                Response.Buffer =true;
                Response.AddHeader("Accept-Language", "zh-tw");
                string name = System.IO.Path.GetFileName(fileRpath);
                System.IO.FileStream files = new FileStream(fileRpath, FileMode.Open, FileAccess.Read, FileShare.Read);
                byte[] byteFile=null;
                if (files.Length == 0)
                {
                    byteFile=new byte[1];
                }
                else
                {
                    byteFile = new byte[files.Length];
                }
                files.Read(byteFile, 0, (int)byteFile.Length);
                files.Close();
             
                Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(name, System.Text.Encoding.UTF8));
                Response.ContentType = "application/octet-stream;charset=gbk";
                Response.BinaryWrite(byteFile);
                Response.End();
              
        }
    }
}

 之前一直用這種下載方式,可是有一次用戶上傳了一個700Mb的文件時報內存溢出的問題,分析了一下原因,用戶的內存只有256M,而下載文件時要創建內存流,導致了內存溢出。

解決方案:1>WriteFile分塊下載,就是每次下載指定數量的多件;

             2>通過超鏈接的方式;

             lblDownLoad.Text = "<a href=‘" + drv["VPath"].ToString() + "‘>下載</a>"

下面是四種實現文件下載的方式:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    //TransmitFile實現下載
    protected void Button1_Click(object sender, EventArgs e)
    {
        /*
         微軟為Response對象提供了一個新的方法TransmitFile來解決使用Response.BinaryWrite
         下載超過400mb的文件時導致Aspnet_wp.exe進程回收而無法成功下載的問題。
         代碼如下:
         */

        Response.ContentType = "application/x-zip-compressed";
        Response.AddHeader("Content-Disposition", "attachment;filename=z.zip");
        string filename = Server.MapPath("DownLoad/z.zip");
        Response.TransmitFile(filename);
    }

    //WriteFile實現下載
    protected void Button2_Click(object sender, EventArgs e)
    {
        /*
         using System.IO;
         
         */

        string fileName ="asd.txt";//客戶端保存的文件名
        string filePath=Server.MapPath("DownLoad/aaa.txt");//路徑

        FileInfo fileInfo = new FileInfo(filePath);
        Response.Clear();
        Response.ClearContent();
        Response.ClearHeaders();
        Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
        Response.AddHeader("Content-Length", fileInfo.Length.ToString());
        Response.AddHeader("Content-Transfer-Encoding", "binary");
        Response.ContentType = "application/octet-stream";
        Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
        Response.WriteFile(fileInfo.FullName);
        Response.Flush();
        Response.End();
    }

    //WriteFile分塊下載
    protected void Button3_Click(object sender, EventArgs e)
    {

        string fileName = "aaa.txt";//客戶端保存的文件名
        string filePath = Server.MapPath("DownLoad/aaa.txt");//路徑

        System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

        if (fileInfo.Exists == true)
        {
            const long ChunkSize = 102400;//100K 每次讀取文件,只讀取100K,這樣可以緩解服務器的壓力
            byte[] buffer = new byte[ChunkSize];

            Response.Clear();
            System.IO.FileStream iStream = System.IO.File.OpenRead(filePath);
            long dataLengthToRead = iStream.Length;//獲取下載的文件總大小
            Response.ContentType = "application/octet-stream";
            Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName));
            while (dataLengthToRead > 0 && Response.IsClientConnected)
            {
                int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//讀取的大小
                Response.OutputStream.Write(buffer, 0, lengthRead);
                Response.Flush();
                dataLengthToRead = dataLengthToRead - lengthRead;
            }
            Response.Close();
        }
    }

    //流方式下載
    protected void Button4_Click(object sender, EventArgs e)
    {
        string fileName = "aaa.txt";//客戶端保存的文件名
        string filePath = Server.MapPath("DownLoad/aaa.txt");//路徑

        //以字符流的形式下載文件
        FileStream fs = new FileStream(filePath, FileMode.Open);
        byte[] bytes = new byte[(int)fs.Length];
        fs.Read(bytes, 0, bytes.Length);
        fs.Close();
        Response.ContentType = "application/octet-stream";
        //通知瀏覽器下載文件而不是打開
        Response.AddHeader("Content-Disposition", "attachment;  filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
        Response.BinaryWrite(bytes);
        Response.Flush();
        Response.End();

    }
}

C#實現文件下載的幾種方式