利用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/aaa.zip"); Response.TransmitFile(filename);
IO的WriteFile實現下載
string fileName ="aaa.zip";//客戶端保存的文件名 string filePath=Server.MapPath("DownLoad/aaa.zip");//路徑 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分塊下載
string fileName = "aaa.zip";//客戶端保存的文件名 string filePath = Server.MapPath("DownLoad/aaa.zip");//路徑 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(); }
//流方式下載
string fileName = "aaa.zip";//客戶端保存的文件名 string filePath = Server.MapPath("DownLoad/aaa.zip");//路徑 //以字符流的形式下載文件 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();
最后一種支持斷點下載
/// <summary> /// 支持斷點續傳的下載大文件的函數 /// </summary> /// <param name="downloadFilePath">被下載文件的路徑,相對和絕對都可以</param> /// <param name="showFileName">顯示給用戶的文件名,可以為空</param> /// <param name="fileType">要下載的文件類型,如果不確定,請留空</param> /// <remarks>用於大文件的下載</remarks> public static void BigFileDownload(string downloadFilePath, string showFileName, string fileType) { downloadFilePath = downloadFilePath.Trim(); if(string.Empty == downloadFilePath) ShowErrorMessage("沒有指定要下載的文件路徑!"); if(downloadFilePath.IndexOf(":") < 0) downloadFilePath = System.Web.HttpContext.Current.Server.MapPath(downloadFilePath); showFileName = showFileName.Trim(); if(string.Empty == showFileName) showFileName = Path.GetFileName(downloadFilePath); showFileName = System.Web.HttpUtility.UrlEncode(System.Web.HttpContext.Current.Request.ContentEncoding.GetBytes(showFileName)); fileType = fileType.Trim(); if(string.Empty == fileType) fileType = "application/octet-stream"; System.Web.HttpContext.Current.Response.Clear(); Stream objStream = null; byte[] btBuffer = new byte[8192]; // 1024*8 = 8Kb int intLength = 0; long lngData2Read = 0; try { using(objStream = new FileStream(downloadFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { lngData2Read = objStream.Length; 輸出HTTP頭信息 while(lngData2Read > 0) { if(HttpContext.Current.Response.IsClientConnected) { intLength = objStream.Read(btBuffer, 0, 8192); HttpContext.Current.Response.OutputStream.Write(btBuffer, 0, intLength); HttpContext.Current.Response.Flush(); lngData2Read -= intLength; btBuffer = new byte[8192]; } else { lngData2Read = -1; } } } } catch(Exception ex) { ShowErrorMessage(ex.Message); } // 結束文件下載,此句不可缺少,否則會把本頁的HTML代碼一起下載文件里 HttpContext.Current.Response.End(); } /// <summary> /// 輸出錯誤信息給用戶,采用客戶端彈出框的方式 /// </summary> /// <param name="errorMessage">錯誤信息的內容</param> internal static void ShowErrorMessage(string errorMessage) { errorMessage = errorMessage.Replace("'", "\""); System.Web.HttpContext.Current.Response.Write("<script language='javascript'>"); System.Web.HttpContext.Current.Response.Write("alert('"); System.Web.HttpContext.Current.Response.Write(errorMessage); System.Web.HttpContext.Current.Response.Write("');</script>"); System.Web.HttpContext.Current.Response.End(); }