1. 程式人生 > >檔案上傳原理及流程

檔案上傳原理及流程

感謝原博主:

http://blog.sina.com.cn/s/blog_8f32dc250100wva8.html

一、HTTP檔案上傳

html
<input type=”file” name=”xxx”> 
type:型別
name:名字
method:post (post與get的區別是,post下引數值不會放在url後面,更加安全)
enctype:屬性規定在傳送到伺服器之前應該如何對錶單資料進行編碼。


form表單
multipart/form-data:不對字元編碼,在使用包含檔案上傳控制元件的表單時,必須使用該值。
對於multipart/form-fata型別的表單,瀏覽器上傳的實體內容中的每個表單欄位元素的資料之間,
用欄位分割線進行分割,兩個分割界線間的內容成為一個分割槽,每個分割槽的內容可以被看做兩部分,
一部分是對錶單元欄位元素進行描述的描述頭,
另一部分是表單元欄位元素的主體內容


欄位(content-type)
-----------------------
描述頭(換行\n)
分割槽(空行\r \n)
\r主體內容
-----------------------


二、伺服器
1.伺服器端程式收到"multipart/form-data"型別的http請求訊息
2.讀取這個請求訊息裡面的實體內容
3.解析每個分割槽的資料
4.從每個分割槽中解析出描述頭和主體內容部分


要在jsp裡面獲得上傳的檔案,就是通過request.getInputStream()來得到上傳的整個post實體的流。
1.用request.getHeader("Content-Type")來取得實體內容的分解字串
2.根據http協議,分析取得的上傳實體流,把檔案部分篩選出來
3.儲存在故武器的磁碟檔案中
4.由於上傳檔案時,form的屬性enctype="multipart/form-data",所以其他表單引數在上傳時無法得到
除了篩選出檔案進行儲存,還應該把其他的引數一起取出儲存,以便在jsp中呼叫


具體方法如下:
1.根據request獲得檔案輸入流
2.依次讀取行,此時進行兩部分內容的處理
 (1)獲取檔名,以filename = "xxx"來標識一個檔案頭
 (2)獲取其他表單值,以name="xxx"來標識一個表單頭
 都以流頭的字元標識為值結束
 
實體內容內部的欄位分隔界線是在content-type頭中指定的欄位分隔界線前面增加了兩個"-"號而形成的。
(由瀏覽器隨機生成,保證上傳內容不重複)


當找到一個分割槽的開始位置後,程式還需要分辨出分割槽中的描述頭和主體內容,並對他們分開儲存。
如何辨別描述頭和主體部分?
每個分割槽的描述頭和主體內容之間有一個空行,描述頭後面有個換行。
因此描述頭和主體之間有"\n","\r","\n","\r"這四個連續的位元組內容進行分割,
並在位元組陣列緩衝區buffer中尋找這個特殊的分割界限來識別他倆。


根據督導的檔案資訊,比如檔名,檔案大小等,判斷是否合法,
合法就返回,不合法就建立同名檔案並將其刪除


日常中推薦使用元件(smartUpload,FileUpload,Cos)
因為:
1.讀取檔案大小限制(fileupload是建立臨時檔案)
2.讀取效率限制


這類元件的使用及封裝方式:
MultipartRequest mu = new MultipartRequest(HttpServletRequest request,Directory,MaxSize,”gbk”);