[转]ASP.NET中常用的文件上传下载方法
生活随笔
收集整理的這篇文章主要介紹了
[转]ASP.NET中常用的文件上传下载方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、如何解決文件上傳大小的限制
2、以文件形式保存到服務器
3、轉換成二進制字節流保存到數據庫以及下載方法
4、上傳Internet上的資源
第一部分:
??? 首先我們來說一下如何解決ASP.NET中的文件上傳大小限制的問題,我們知道在默認情況下ASP.NET的文件上傳大小限制為2M,一般情況下,我們可以采用更改WEB.Config文件來自定義最大文件大小,如下:
<httpRuntime?executionTimeout="300"?maxRequestLength="40960"?useFullyQualifiedRedirectUrl="false"/> 這樣上傳文件的最大值就變成了4M,但這樣并不能讓我們無限的擴大MaxRequestLength的值,因為ASP.NET會將全部文件載入內存后,再加以處理。解決的方法是利用隱含的HttpWorkerRequest,用它的GetPreloadedEntityBody和ReadEntityBody方法從IIS為ASP.NET建立的pipe里分塊讀取數據。實現方法如下:
IServiceProviderprovider=(IServiceProvider)HttpContext.Current;
HttpWorkerRequestwr=(HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
byte[]bs=wr.GetPreloadedEntityBody();
.
if(!wr.IsEntireEntityBodyIsPreloaded())
{
intn=1024;
byte[]bs2=newbyte[n];
while(wr.ReadEntityBody(bs2,n)>0)
{
..
}
} 這樣就可以解決了大文件的上傳問題了。
第二部分:
??? 下面我們來介紹如何以文件形式將客戶端的一個文件上傳到服務器并返回上傳文件的一些基本信息
首先我們定義一個類,用來存儲上傳的文件的信息(返回時需要)。
public?class?FileUpLoad
{
???public?FileUpLoad()
???{
???}
/**////?<summary>
????????///?上傳文件名稱
????????///?</summary>
????????public?string?FileName
????????{
????????????get
????????????{
????????????????return?fileName;
????????????}
????????????set
????????????{
????????????????fileName?=?value;
????????????}
????????}
????????private?string?fileName;
????????/**////?<summary>
????????///?上傳文件路徑
????????///?</summary>
????????public?string?FilePath
????????{
????????????get
????????????{
????????????????return?filepath;
????????????}
????????????set
????????????{
????????????????filepath?=?value;
????????????}
????????}
????????private?string?filepath;
????????
????????/**////?<summary>
????????///?文件擴展名
????????///?</summary>
????????public?string?FileExtension
????????{
????????????get
????????????{
????????????????return?fileExtension;
????????????}
????????????set
????????????{
????????????
????????????????fileExtension?=?value;
????????????}
????????????????
????????}
????????private?string?fileExtension;
}
<Application>????
????<FileUpLoad>
???????<Format>.jpg|.gif|.png|.bmp</Format>
????</FileUpLoad>
</Application>
這樣我們就可以開始寫我們的上傳文件的方法了,如下:
public?FileUpLoad?UpLoadFile(HtmlInputFile?InputFile,string?filePath,string?myfileName,bool?isRandom)
????????{
????????????
????????????FileUpLoad?fp?=?new?FileUpLoad();
????????????string?fileName,fileExtension;
????????????string?saveName;
????????????
????????????//
????????????//建立上傳對象
????????????//
????????????HttpPostedFile?postedFile?=?InputFile.PostedFile;
????????????fileName????????=?System.IO.Path.GetFileName(postedFile.FileName);
????????????fileExtension????=?System.IO.Path.GetExtension(fileName);
????????????
????????????//
????????????//根據類型確定文件格式
????????????//
????????????AppConfig?app?=?new?AppConfig();
????????????string?format?=?app.GetPath("FileUpLoad/Format");
????????????//
????????????//如果格式都不符合則返回
????????????//
????????????if(format.IndexOf(fileExtension)==-1)
????????????{
????????????????throw?new?ApplicationException("上傳數據格式不合法");
????????????}
????????????????
????????????//
????????????//根據日期和隨機數生成隨機的文件名
????????????//
????????????if(myfileName?!=?string.Empty)
????????????{
????????????????fileName?=?myfileName;????????????
????????????}
????????????if(isRandom)
????????????{
????????????????Random?objRand?=?new?Random();
????????????????System.DateTime?date?=?DateTime.Now;
????????????????//生成隨機文件名
????????????????saveName?=?date.Year.ToString()?+?date.Month.ToString()?+?date.Day.ToString()?+?date.Hour.ToString()?+?date.Minute.ToString()?
????????????????????+?date.Second.ToString()?+?Convert.ToString(objRand.Next(99)*97?+?100);
????????????????fileName?=?saveName?+?fileExtension;
????????????}
????????????
????????????string?phyPath?=?HttpContext.Current.Request.MapPath(filePath);
????????????//判斷路徑是否存在,若不存在則創建路徑
????????????DirectoryInfo?upDir?=?new?DirectoryInfo(phyPath);
????????????if(!upDir.Exists)
????????????{
????????????????upDir.Create();
????????????}
????????????//
????????????//保存文件
????????????//
????????????try
????????????{
????????????????postedFile.SaveAs(phyPath?+?fileName);
????????????????fp.FilePath?=??filePath??+?fileName;
????????????????fp.FileExtension?=?fileExtension;
????????????????fp.FileName?=?fileName;
????????????}
????????????catch
????????????{
????????????????throw?new?ApplicationException("上傳失敗!");
????????????}
????????????//返回上傳文件的信息
????????????return?fp;
????????
????????
????????}
{
?????????//獲取由客戶端指定的上傳文件的訪問
?????????HttpPostedFile?upFile=f_IFile.PostedFile;
?????????//得到上傳文件的長度
????????????????int?upFileLength=upFile.ContentLength;?
?????????//得到上傳文件的客戶端MIME類型
????????????????string?contentType?=?upFile.ContentType;
????????????????byte[]?FileArray=new?Byte[upFileLength];
?
????????????????Stream?fileStream=upFile.InputStream;?
????????????????
????????????????fileStream.Read(FileArray,0,upFileLength);
????????
????????return?FileArray;
}
這個方法返回的就是上傳的文件的二進制字節流,這樣我們就可以將它保存到數據庫了。下面說一下這種形式的下載,也許你會想到這種方式的下載就是新建一個aspx頁面,然后在它的Page_Load()事件里取出二進制字節流,然后再讀出來就可以了,其實這種方法是不可取的,在實際的運用中也許會出現無法打開某站點的錯誤,我一般采用下面的方法:
首先,在Web.config中加入:
<add?verb="*"?path="openfile.aspx"?type="RuixinOA.Web.BaseClass.OpenFile,?RuixinOA.Web"/>
這表示我打開openfile.aspx這個頁面時,系統就會自動轉到執行RuixinOA.Web.BaseClass.OpenFile 這個類里的方法,具體實現如下:
using?System;
using?System.Data;
using?System.Web;
using?System.IO;
using?Ruixin.WorkFlowDB;
using?RXSuite.Base;
using?RXSuite.Component;
using?RuixinOA.BusinessFacade;
namespace?RuixinOA.Web.BaseClass
{
????/**////?<summary>
????///?NetUFile?的摘要說明。
????///?</summary>
????public?class?OpenFile?:?IHttpHandler
????{
????????public?void?ProcessRequest(HttpContext?context)?
????????{
????????????
????????????//從數據庫中取出要下載的文件信息
????????????RuixinOA.BusinessFacade.RX_OA_FileManager?os?=?new?RX_OA_FileManager();
????????????EntityData?data?=?os.GetFileDetail(id);
????????????if(data?!=?null?&&?data.Tables["RX_OA_File"].Rows.Count?>?0)
????????????{
????????????????DataRow?dr?=?(DataRow)data.Tables["RX_OA_File"].Rows[0];
????????????????context.Response.Buffer?=?true;
????????????????context.Response.Clear();
????????????????context.Response.ContentType?=?dr["CContentType"].ToString();?
????????????????context.Response.AddHeader("Content-Disposition","attachment;filename="?+?HttpUtility.UrlEncode(dr["CTitle"].ToString()));
????????????????context.Response.BinaryWrite((Byte[])dr["CContent"]);
????????????????context.Response.Flush();
????????????????context.Response.End();
????????????}
????????????????????????
????????}
????????public?bool?IsReusable?
????????{?
????????????get?{?return?true;}?
????????}
????}
}
HttpContext.Current.Response.Charset?="";
HttpContext.Current.Response.ContentEncoding?=System.Text.Encoding.GetEncoding("utf-8");
HttpContext.Current.Response.ContentType?="application/msword";
pn_upload.Page.EnableViewState?=false;
System.IO.StringWriter??tw?=?new?System.IO.StringWriter()?;
System.Web.UI.HtmlTextWriter?hw?=?new?System.Web.UI.HtmlTextWriter(tw);
pn_upload.RenderControl(hw);
HttpContext.Current.Response.Write(tw.ToString());
HttpContext.Current.Response.End();
HttpWebResponse?hwr?=?(HttpWebResponse)hwq.GetResponse();
byte[]?bytes?=?new?byte[hwr.ContentLength];
Stream?stream?=?hwr.GetResponseStream();
stream.Read(bytes,0,Convert.ToInt32(hwr.ContentLength));
//HttpContext.Current.Response.BinaryWrite(bytes);
2、以文件形式保存到服務器
3、轉換成二進制字節流保存到數據庫以及下載方法
4、上傳Internet上的資源
第一部分:
??? 首先我們來說一下如何解決ASP.NET中的文件上傳大小限制的問題,我們知道在默認情況下ASP.NET的文件上傳大小限制為2M,一般情況下,我們可以采用更改WEB.Config文件來自定義最大文件大小,如下:
<httpRuntime?executionTimeout="300"?maxRequestLength="40960"?useFullyQualifiedRedirectUrl="false"/> 這樣上傳文件的最大值就變成了4M,但這樣并不能讓我們無限的擴大MaxRequestLength的值,因為ASP.NET會將全部文件載入內存后,再加以處理。解決的方法是利用隱含的HttpWorkerRequest,用它的GetPreloadedEntityBody和ReadEntityBody方法從IIS為ASP.NET建立的pipe里分塊讀取數據。實現方法如下:
IServiceProviderprovider=(IServiceProvider)HttpContext.Current;
HttpWorkerRequestwr=(HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
byte[]bs=wr.GetPreloadedEntityBody();
.
if(!wr.IsEntireEntityBodyIsPreloaded())
{
intn=1024;
byte[]bs2=newbyte[n];
while(wr.ReadEntityBody(bs2,n)>0)
{
..
}
} 這樣就可以解決了大文件的上傳問題了。
第二部分:
??? 下面我們來介紹如何以文件形式將客戶端的一個文件上傳到服務器并返回上傳文件的一些基本信息
首先我們定義一個類,用來存儲上傳的文件的信息(返回時需要)。
public?class?FileUpLoad
{
???public?FileUpLoad()
???{
???}
/**////?<summary>
????????///?上傳文件名稱
????????///?</summary>
????????public?string?FileName
????????{
????????????get
????????????{
????????????????return?fileName;
????????????}
????????????set
????????????{
????????????????fileName?=?value;
????????????}
????????}
????????private?string?fileName;
????????/**////?<summary>
????????///?上傳文件路徑
????????///?</summary>
????????public?string?FilePath
????????{
????????????get
????????????{
????????????????return?filepath;
????????????}
????????????set
????????????{
????????????????filepath?=?value;
????????????}
????????}
????????private?string?filepath;
????????
????????/**////?<summary>
????????///?文件擴展名
????????///?</summary>
????????public?string?FileExtension
????????{
????????????get
????????????{
????????????????return?fileExtension;
????????????}
????????????set
????????????{
????????????
????????????????fileExtension?=?value;
????????????}
????????????????
????????}
????????private?string?fileExtension;
}
另外我們還可以在配置文件中限制上傳文件的格式(App.Config):
<Application>????
????<FileUpLoad>
???????<Format>.jpg|.gif|.png|.bmp</Format>
????</FileUpLoad>
</Application>
這樣我們就可以開始寫我們的上傳文件的方法了,如下:
public?FileUpLoad?UpLoadFile(HtmlInputFile?InputFile,string?filePath,string?myfileName,bool?isRandom)
????????{
????????????
????????????FileUpLoad?fp?=?new?FileUpLoad();
????????????string?fileName,fileExtension;
????????????string?saveName;
????????????
????????????//
????????????//建立上傳對象
????????????//
????????????HttpPostedFile?postedFile?=?InputFile.PostedFile;
????????????fileName????????=?System.IO.Path.GetFileName(postedFile.FileName);
????????????fileExtension????=?System.IO.Path.GetExtension(fileName);
????????????
????????????//
????????????//根據類型確定文件格式
????????????//
????????????AppConfig?app?=?new?AppConfig();
????????????string?format?=?app.GetPath("FileUpLoad/Format");
????????????//
????????????//如果格式都不符合則返回
????????????//
????????????if(format.IndexOf(fileExtension)==-1)
????????????{
????????????????throw?new?ApplicationException("上傳數據格式不合法");
????????????}
????????????????
????????????//
????????????//根據日期和隨機數生成隨機的文件名
????????????//
????????????if(myfileName?!=?string.Empty)
????????????{
????????????????fileName?=?myfileName;????????????
????????????}
????????????if(isRandom)
????????????{
????????????????Random?objRand?=?new?Random();
????????????????System.DateTime?date?=?DateTime.Now;
????????????????//生成隨機文件名
????????????????saveName?=?date.Year.ToString()?+?date.Month.ToString()?+?date.Day.ToString()?+?date.Hour.ToString()?+?date.Minute.ToString()?
????????????????????+?date.Second.ToString()?+?Convert.ToString(objRand.Next(99)*97?+?100);
????????????????fileName?=?saveName?+?fileExtension;
????????????}
????????????
????????????string?phyPath?=?HttpContext.Current.Request.MapPath(filePath);
????????????//判斷路徑是否存在,若不存在則創建路徑
????????????DirectoryInfo?upDir?=?new?DirectoryInfo(phyPath);
????????????if(!upDir.Exists)
????????????{
????????????????upDir.Create();
????????????}
????????????//
????????????//保存文件
????????????//
????????????try
????????????{
????????????????postedFile.SaveAs(phyPath?+?fileName);
????????????????fp.FilePath?=??filePath??+?fileName;
????????????????fp.FileExtension?=?fileExtension;
????????????????fp.FileName?=?fileName;
????????????}
????????????catch
????????????{
????????????????throw?new?ApplicationException("上傳失敗!");
????????????}
????????????//返回上傳文件的信息
????????????return?fp;
????????
????????
????????}
然后我們在上傳文件的時候就可以調用這個方法了,將返回的文件信息保存到數據庫中,至于下載,就直接打開那個路徑就OK了。
第三部分:
??? 這里我們主要說一下如何以二進制的形式上傳文件以及下載。首先說上傳,方法如下:
{
?????????//獲取由客戶端指定的上傳文件的訪問
?????????HttpPostedFile?upFile=f_IFile.PostedFile;
?????????//得到上傳文件的長度
????????????????int?upFileLength=upFile.ContentLength;?
?????????//得到上傳文件的客戶端MIME類型
????????????????string?contentType?=?upFile.ContentType;
????????????????byte[]?FileArray=new?Byte[upFileLength];
?
????????????????Stream?fileStream=upFile.InputStream;?
????????????????
????????????????fileStream.Read(FileArray,0,upFileLength);
????????
????????return?FileArray;
}
這個方法返回的就是上傳的文件的二進制字節流,這樣我們就可以將它保存到數據庫了。下面說一下這種形式的下載,也許你會想到這種方式的下載就是新建一個aspx頁面,然后在它的Page_Load()事件里取出二進制字節流,然后再讀出來就可以了,其實這種方法是不可取的,在實際的運用中也許會出現無法打開某站點的錯誤,我一般采用下面的方法:
首先,在Web.config中加入:
<add?verb="*"?path="openfile.aspx"?type="RuixinOA.Web.BaseClass.OpenFile,?RuixinOA.Web"/>
這表示我打開openfile.aspx這個頁面時,系統就會自動轉到執行RuixinOA.Web.BaseClass.OpenFile 這個類里的方法,具體實現如下:
using?System;
using?System.Data;
using?System.Web;
using?System.IO;
using?Ruixin.WorkFlowDB;
using?RXSuite.Base;
using?RXSuite.Component;
using?RuixinOA.BusinessFacade;
namespace?RuixinOA.Web.BaseClass
{
????/**////?<summary>
????///?NetUFile?的摘要說明。
????///?</summary>
????public?class?OpenFile?:?IHttpHandler
????{
????????public?void?ProcessRequest(HttpContext?context)?
????????{
????????????
????????????//從數據庫中取出要下載的文件信息
????????????RuixinOA.BusinessFacade.RX_OA_FileManager?os?=?new?RX_OA_FileManager();
????????????EntityData?data?=?os.GetFileDetail(id);
????????????if(data?!=?null?&&?data.Tables["RX_OA_File"].Rows.Count?>?0)
????????????{
????????????????DataRow?dr?=?(DataRow)data.Tables["RX_OA_File"].Rows[0];
????????????????context.Response.Buffer?=?true;
????????????????context.Response.Clear();
????????????????context.Response.ContentType?=?dr["CContentType"].ToString();?
????????????????context.Response.AddHeader("Content-Disposition","attachment;filename="?+?HttpUtility.UrlEncode(dr["CTitle"].ToString()));
????????????????context.Response.BinaryWrite((Byte[])dr["CContent"]);
????????????????context.Response.Flush();
????????????????context.Response.End();
????????????}
????????????????????????
????????}
????????public?bool?IsReusable?
????????{?
????????????get?{?return?true;}?
????????}
????}
}
執行上面的方法后,系統會提示用戶選擇直接打開還是下載。
第四部分:
將動態頁面轉換為二進制流:
由于我們一般的文件上傳都是一個物理上存在的文件,而這里的流程標簽頁面是根據ID號動態生成的,剛開始我用了一個比較笨的方法,思路是:先將這個頁面保存到服務器的硬盤上,然后再上傳到數據庫中。方法實現如下:
?
? HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=upload.doc");HttpContext.Current.Response.Charset?="";
HttpContext.Current.Response.ContentEncoding?=System.Text.Encoding.GetEncoding("utf-8");
HttpContext.Current.Response.ContentType?="application/msword";
pn_upload.Page.EnableViewState?=false;
System.IO.StringWriter??tw?=?new?System.IO.StringWriter()?;
System.Web.UI.HtmlTextWriter?hw?=?new?System.Web.UI.HtmlTextWriter(tw);
pn_upload.RenderControl(hw);
HttpContext.Current.Response.Write(tw.ToString());
HttpContext.Current.Response.End();
這樣頁面就以Word格式保存到計算機上了,然后執行上傳到數據庫的操作,這樣也能實現客戶的需求,但給人的感覺總是怪怪的,肯定是個下下策了。
首先需要引用 System.Net 這個命名空間,然后操作如下:
HttpWebRequest?hwq?=?(HttpWebRequest)WebRequest.Create("http://localhost/pwtest/webform1.aspx");HttpWebResponse?hwr?=?(HttpWebResponse)hwq.GetResponse();
byte[]?bytes?=?new?byte[hwr.ContentLength];
Stream?stream?=?hwr.GetResponseStream();
stream.Read(bytes,0,Convert.ToInt32(hwr.ContentLength));
//HttpContext.Current.Response.BinaryWrite(bytes);
HttpWebRequest 可以從Internet上讀取文件,因此可以很好的解決這個問題。
引自:? http://pw.cnblogs.com/archive/2006/05/24/408427.html
?
轉載于:https://www.cnblogs.com/leeyon/archive/2009/03/16/1413254.html
總結
以上是生活随笔為你收集整理的[转]ASP.NET中常用的文件上传下载方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 购物车实例 转载至http://www.
- 下一篇: TStringList的用法