asp.net從ftp下載大文件再輸出瀏覽器的實(shí)現(xiàn)(對(duì)文件同時(shí)進(jìn)行讀寫(xiě)操作)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
很多時(shí)候安全起見(jiàn),不會(huì)讓用戶通過(guò)瀏覽器直接從ftp下載文件。這時(shí)我們需要web從ftp下載文件再輸出到瀏覽器,對(duì)于小文件我們可以一次性讀到memorystream,然后輸出;但是大文件這樣實(shí)現(xiàn)就會(huì)導(dǎo)致服務(wù)器內(nèi)存爆炸,此時(shí)我們可以利用filestream,一邊從ftp下載數(shù)據(jù)到本地,一邊從本地輸出到用戶客戶端,這樣對(duì)于再大的文件都不會(huì)影響內(nèi)存。 以下是通過(guò)異步的方式實(shí)現(xiàn)對(duì)下載文件同時(shí)進(jìn)行讀寫(xiě)操作的代碼(.net framwork 4.5),MD5驗(yàn)證一致: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication6 { public partial class WebForm1 : System.Web.UI.Page { Aspose.Network.Ftp.FtpClient ftpclient = new Aspose.Network.Ftp.FtpClient("xxxx", "xxx", "xxx"); protected void Page_Load(object sender, EventArgs e) { } string fileName = "C4F4EEP0CX00_ECN-52966A.exe"; string downloadPath = string.Empty; string refilename = string.Empty; public async void DownLoadFileAsync() { string extension = Path.GetExtension(fileName); refilename = Path.GetFileNameWithoutExtension(fileName) + DateTime.Now.ToString("yyyyMMddHHmmssffff") + extension; downloadPath = Server.MapPath(Path.Combine("tempFile", refilename)); try { ftpclient.Connect(); ftpclient.Login(); ftpclient.KeepAlive(); //Task.Run()需要.net4.5及以上版本的支持 await Task.Run(() => { ftpclient.Download("CLIENT_TMP//" + fileName, downloadPath); }); //以下代碼支持.net 4.0 ,但是需要額外在項(xiàng)目中加一個(gè)類TaskEx //await Task.Factory.StartNew(() => { ftpclient.Download("CLIENT_TMP//" + fileName, downloadPath); }); } catch { throw; } finally { ftpclient.Disconnect(); } } //要使用異步,頁(yè)面配置頭需要加Async="true" //<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication6.WebForm1" Async="true" %> protected void Button1_Click(object sender, EventArgs e) { try { //異步從ftp下載文件到web服務(wù)器本地文件夾 DownLoadFileAsync(); Response.Clear();//清空緩沖區(qū) Response.Buffer = false;//不從緩沖區(qū)返回?cái)?shù)據(jù) Response.ContentType = "application/ctet-stream";//設(shè)置輸出流 Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName + ";"); Response.AddHeader("Connection", "Keep-Alive");//長(zhǎng)連接 Thread.Sleep(2000);//等待異步創(chuàng)建文件成功,避免fileStream初始化失敗 //FileAccess.Read表示當(dāng)前流只能讀,不能寫(xiě),如果后續(xù)有寫(xiě)操作會(huì)報(bào)錯(cuò) //FileShare.ReadWrite 表示當(dāng)前流在操作磁盤(pán)文件過(guò)程中其他流可以讀也可以寫(xiě). using (FileStream fileStream = new FileStream(downloadPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (BinaryReader br = new BinaryReader(fileStream)) { int length = 2048; //獲取br.BaseStream.Length時(shí)值會(huì)隨著ftp下載而變化,每次獲取都會(huì)更新 //br.ReadBytes()讀取完后br.BaseStream.Position會(huì)前移. while (br.BaseStream.Position < br.BaseStream.Length) { length = br.BaseStream.Length - br.BaseStream.Position > 2048 ? 2048 : (int)(br.BaseStream.Length - br.BaseStream.Position); Response.BinaryWrite(br.ReadBytes(length)); } } } } catch (Exception ex) { Response.Write($"<script>alert(''下載失敗:{ex.Message}'')</script>"); } finally { //下載完成后刪除本地文件夾的文件 try { File.Delete(downloadPath); } catch { } Response.End(); } } } } 該文章在 2021/3/3 11:12:04 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |