Asp.NET大文件上传组件开发总结(二)---提取文件内容
不知地震什么時(shí)候結(jié)束,為了給老婆小孩守夜,看來(lái)還不能睡,那就把第二篇也寫(xiě)了吧,只是不知對(duì)大家有沒(méi)有用喲。
為了提供文件內(nèi)容,我們需要首先需確定客戶請(qǐng)求中發(fā)送的有文件內(nèi)容,然后確定文件內(nèi)容的位置。這部分對(duì)應(yīng)的代碼如下:
?1HttpApplication?app?=?sender?as?HttpApplication;?2????????????HttpWorkerRequest?request?=?GetWorkerRequest(app.Context);
?3????????????
?4????????????if?(!IsUploadRequest(app.Request))?return;?//不是文件上傳,則退出
?5????????????
?6????????????string?sContentType?=?app.Request.ContentType.ToLower();
?7????????????byte[]?arrBoundary?=?GetMultipartBoundary(sContentType);
?8????????????int?ContentLength?=?app.Request.ContentLength;?//信息體的總長(zhǎng)度
?9
10????????????DataReader?dataReader?=?new?DataReader(app.Context.Request.ContentEncoding,?arrBoundary);
11????????????DateTime?startDate?=?DateTime.Now;
12????????????byte[]?arrBuffer?=?request.GetPreloadedEntityBody();
13????????????if?(arrBuffer?==?null)
14????????????{
15????????????????arrBuffer?=?new?Byte[0];
16????????????????tempFile.Close();
17????????????????return;?//沒(méi)有讀取到信息體
18????????????}
19????????????else
20????????????{
21?????????????這里是對(duì)文件內(nèi)容的處理
22????????????}
上面的代碼中,我們先獲取Asp.NET對(duì)客戶端請(qǐng)求的處理對(duì)象HttpWorkerRequest,然后根據(jù)這個(gè)對(duì)象的ContentType屬性是否為multipart/form-data來(lái)確定對(duì)應(yīng)的請(qǐng)求是否有上傳文件,如果沒(méi)有上傳文件,就不處理此請(qǐng)求,以提高處理效率。這樣處理的依據(jù)是,在有文件上傳的HTML Form中,對(duì)應(yīng)的enctype屬性為multipart/form-data。這樣就解決了確定客戶端請(qǐng)求中是否發(fā)送有文件內(nèi)容。
要確定文件的內(nèi)容位置,為此我們需要使用Reflector工具反編譯System.Web.dll中HttpRequest的代碼,可以發(fā)現(xiàn)有一個(gè)GetEntireRawContent方法,這個(gè)方法里,調(diào)用了HttpWorkerRequest對(duì)的GetPreloadedEntityBody方法來(lái)獲取數(shù)據(jù),可喜的是,這個(gè)方法是Public的,所以我們也可以直接調(diào)此方法來(lái)獲取客戶端發(fā)送的數(shù)據(jù)。
獲取數(shù)據(jù)后,我們可以將這些數(shù)據(jù)寫(xiě)入到一個(gè)文件中,這些數(shù)據(jù)是byte[]類(lèi)型的,在寫(xiě)入文件時(shí),因?yàn)镠ttp協(xié)議是基于文本的,所以我們可以采用System.Text.Encoding.GetString方法,將這些字節(jié)數(shù)組編碼成字符串,我這里的編碼采用ASCII,只是這樣請(qǐng)求中的中文就成了亂碼。這樣就可以獲取請(qǐng)求的內(nèi)容的文體格式,以方便我們分析(在代碼中,這個(gè)寫(xiě)文件的功能我已去除,因?yàn)檫@里寫(xiě)全部請(qǐng)求內(nèi)容只是用于分析使用,請(qǐng)參見(jiàn)第一篇文章中我列出的請(qǐng)求內(nèi)容示例)。
通過(guò)分析這些請(qǐng)求內(nèi)容,我們可以發(fā)現(xiàn):每個(gè)頁(yè)面控件,均可以在這里找到對(duì)應(yīng)的內(nèi)容,兩個(gè)控件內(nèi)容間是用字符串“-----------------------------7d81e441d025c”分隔的。同時(shí)在我們反編譯System.Web.dll中HttpRequest的代碼時(shí),也可以發(fā)有GetMultipartBoundary這個(gè)方法,這個(gè)方法我們可以從字面意思得知是取分隔標(biāo)識(shí)。我們把這個(gè)方法提取出來(lái):
?1private?byte[]?GetMultipartBoundary()
?2{
?3????string?attributeFromHeader?=?GetAttributeFromHeader(this.ContentType,?"boundary");
?4????if?(attributeFromHeader?==?null)
?5????{
?6????????return?null;
?7????}
?8????attributeFromHeader?=?"--"?+?attributeFromHeader;
?9????return?Encoding.ASCII.GetBytes(attributeFromHeader.ToCharArray());
10}
然后我們采用這個(gè)方法,就可以從請(qǐng)求的內(nèi)容中提取出類(lèi)似“-----------------------------7d81e441d025c”這樣的字符串。這樣,我們就可以分隔頁(yè)面內(nèi)不同控件的內(nèi)容了。
最后,我們分析文件上傳控件的內(nèi)容:
Content-Type:?application/x-rar-compressed
Rar!???s
我們可以發(fā)現(xiàn),文件上傳控件有一個(gè)filename屬性,然后,下一行指定文件的MIME類(lèi)型,隨后這個(gè)空白行,在空白行下面,直到下一處類(lèi)似“-----------------------------7d81e441d025c”標(biāo)志字符串間,就是客戶端發(fā)送的文件內(nèi)容。我們只需把這些內(nèi)容寫(xiě)入到服務(wù)器文件中即可。
這里,文件內(nèi)容的提取的問(wèn)題就可以解決了。在提取文件內(nèi)容時(shí),對(duì)處理標(biāo)志字符串時(shí)需要特別處理,防止標(biāo)志字符分別讀取到兩個(gè)緩沖區(qū)中,所以這部分代碼還是比較多的,具體請(qǐng)參看源代碼中的DataReader類(lèi)。
第二篇就寫(xiě)到這,實(shí)在是太困了,后面的等一下再寫(xiě)吧!
轉(zhuǎn)載于:https://www.cnblogs.com/bashan/archive/2008/05/14/1196057.html
總結(jié)
以上是生活随笔為你收集整理的Asp.NET大文件上传组件开发总结(二)---提取文件内容的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 项目测试经验交流
- 下一篇: .Net 中的序列化与反序列化 (转)