【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容

iDotNetSpace發表於2008-05-20

不知地震什麼時候結束,為了給老婆小孩守夜,看來還不能睡,那就把第二篇也寫了吧,只是不知對大家有沒有用喲。

為了提供檔案內容,我們需要首先需確定客戶請求中傳送的有檔案內容,然後確定檔案內容的位置。這部分對應的程式碼如下:

 1【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容HttpApplication app = sender as HttpApplication;
 2【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            HttpWorkerRequest request = GetWorkerRequest(app.Context);
 3【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            
 4【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            if (!IsUploadRequest(app.Request)) return//不是檔案上傳,則退出
 5【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            
 6【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            string sContentType = app.Request.ContentType.ToLower();
 7【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            byte[] arrBoundary = GetMultipartBoundary(sContentType);
 8【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            int ContentLength = app.Request.ContentLength; //資訊體的總長度
 9【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容
10【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            DataReader dataReader = new DataReader(app.Context.Request.ContentEncoding, arrBoundary);
11【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            DateTime startDate = DateTime.Now;
12【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            byte[] arrBuffer = request.GetPreloadedEntityBody();
13【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            if (arrBuffer == null)
14【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            {
15【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容                arrBuffer = new Byte[0];
16【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容                tempFile.Close();
17【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容                return//沒有讀取到資訊體
18【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            }

19【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            else
20【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            {
21【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容             【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容這裡是對檔案內容的處理
22【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容            }

上面的程式碼中,我們先獲取Asp.NET對客戶端請求的處理物件HttpWorkerRequest,然後根據這個物件的ContentType屬性是否為multipart/form-data來確定對應的請求是否有上傳檔案,如果沒有上傳檔案,就不處理此請求,以提高處理效率。這樣處理的依據是,在有檔案上傳的HTML Form中,對應的enctype屬性為multipart/form-data。這樣就解決了確定客戶端請求中是否傳送有檔案內容。
要確定檔案的內容位置,為此我們需要使用Reflector工具反編譯System.Web.dllHttpRequest的程式碼,可以發現有一個GetEntireRawContent方法,這個方法裡,呼叫了HttpWorkerRequest對的GetPreloadedEntityBody方法來獲取資料,可喜的是,這個方法是Public的,所以我們也可以直接調此方法來獲取客戶端傳送的資料。
獲取資料後,我們可以將這些資料寫入到一個檔案中,這些資料是byte[]型別的,在寫入檔案時,因為Http協議是基於文字的,所以我們可以採用System.Text.Encoding.GetString方法,將這些位元組陣列編碼成字串,我這裡的編碼採用ASCII,只是這樣請求中的中文就成了亂碼。這樣就可以獲取請求的內容的文體格式,以方便我們分析(在程式碼中,這個寫檔案的功能我已去除,因為這裡寫全部請求內容只是用於分析使用,請參見第一篇文章中我列出的請求內容示例)。
通過分析這些請求內容,我們可以發現:每個頁面控制元件,均可以在這裡找到對應的內容,兩個控制元件內容間是用字串“-----------------------------7d81e441d025c”分隔的。同時在我們反編譯System.Web.dllHttpRequest的程式碼時,也可以發有GetMultipartBoundary這個方法,這個方法我們可以從字面意思得知是取分隔標識。我們把這個方法提取出來:
 1【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容private byte[] GetMultipartBoundary()
 2【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容{
 3【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容    string attributeFromHeader = GetAttributeFromHeader(this.ContentType, "boundary");
 4【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容    if (attributeFromHeader == null)
 5【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容    {
 6【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容        return null;
 7【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容    }

 8【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容    attributeFromHeader = "--" + attributeFromHeader;
 9【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容    return Encoding.ASCII.GetBytes(attributeFromHeader.ToCharArray());
10【巴山】Asp.NET大檔案上傳元件開發總結(二)---提取檔案內容}


然後我們採用這個方法,就可以從請求的內容中提取出類似“-----------------------------7d81e441d025c”這樣的字串。這樣,我們就可以分隔頁面內不同控制元件的內容了。
最後,我們分析檔案上傳控制元件的內容:

Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\Administrator\??????\componentart.web.ui.rar"
Content
-Type: application/x-rar-compressed

Rar
! ??s


我們可以發現,檔案上傳控制元件有一個filename屬性,然後,下一行指定檔案的MIME型別,隨後這個空白行,在空白行下面,直到下一處類似“-----------------------------7d81e441d025c”標誌字串間,就是客戶端傳送的檔案內容。我們只需把這些內容寫入到伺服器檔案中即可。

這裡,檔案內容的提取的問題就可以解決了。在提取檔案內容時,對處理標誌字串時需要特別處理,防止標誌字元分別讀取到兩個緩衝區中,所以這部分程式碼還是比較多的,具體請參看原始碼中的DataReader類。

第二篇就寫到這,實在是太困了,後面的等一下再寫吧!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-281051/,如需轉載,請註明出處,否則將追究法律責任。

相關文章