文件上傳
(一)文件上傳的概述
一、什么是文件上傳
? ? 文件上傳:將本地的文件通過流寫入到服務(wù)器的過程
二、為什么要學(xué)習(xí)文件上傳
? ? 實際開發(fā)中有很多應(yīng)用:
? ? ? ? QQ空間上傳圖片
? ? ? ? 招聘網(wǎng)站上傳簡歷
三瓷耙、文件上傳的技術(shù)
? ? JSPSmartUpload:應(yīng)用在JSP上的文件上傳和下載的組件
? ? FileUpload:應(yīng)用在Java環(huán)境上的文件上傳的功能
? ? Servlet3.0:提供了文件上傳的功能
? ? Struts2:提供了文件上傳的功能
四、文件上傳的三個要素
? ? 1、表單的提交的方式需要是POST(因為GET有大小限制)
? ? 2、表單中需要有<input type="file">元素免糕,還需要有name屬性和值
? ? 3、表單屬性必須設(shè)置enctype="multipart/form-data"
(二)文件上傳的原理分析
一忧侧、抓包分析
1石窑、沒有設(shè)置enctype屬性
POST /web06/jsp/upload.jsp HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 23
Cache-Control: max-age=0
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Referer: http://localhost:8080/web06/jsp/upload.jsp
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=5EC0B8AC2ED01283DEE896BC835C05FB
info=aaa&upload=aaa.txt
? ? ? ? *注意:沒有文件上傳中的文件的具體內(nèi)容
2、設(shè)置enctype屬性
POST /web06/jsp/upload.jsp HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------66193578536799190642897124112
Content-Length: 344
Origin: http://localhost:8080
Connection: keep-alive
Referer: http://localhost:8080/web06/jsp/upload.jsp
Cookie: JSESSIONID=00D32978472B2FE2E35796855713EE40; Pycharm-8dbeb98c=1f31b81e-d44c-45f8-95c1-2b06c10aea65
Upgrade-Insecure-Requests: 1
-----------------------------66193578536799190642897124112
Content-Disposition: form-data; name="info"
aaa
-----------------------------66193578536799190642897124112
Content-Disposition: form-data; name="upload"; filename="aaa.txt"
Content-Type: text/plain
hello world!!
-----------------------------66193578536799190642897124112--
二苍柏、文件上傳的原理分析
手動實現(xiàn)文件上傳:
(1)獲得分割線
(2)獲得請求體的所有內(nèi)容:request.getInputStream();
(3)利用分割線將獲得內(nèi)容進行分割
(4)判斷是普通項還是文件上傳項
普通項:獲得普通項名稱和值
文件上傳項:獲得文件名稱和文件內(nèi)容尼斧,通過流寫到服務(wù)器上
(三)文件上傳的代碼實現(xiàn)
一、引入文件上傳的相關(guān)jar包
二试吁、編寫文件上傳的頁面
三、編寫文件上傳的Servlet
(四)文件上傳的API
一楼咳、DiskFileItemFactory:磁盤文件項工廠
1熄捍、構(gòu)造方法:
DiskFileItemFactory()
DiskFileItemFactory(int sizeThreshold, File repository)
sizeThreshold:用來設(shè)置文件上傳的緩沖區(qū)的大小,默認值為10KB
repository:用來設(shè)置文件上傳過程中所產(chǎn)生的臨時文件存放的路徑
2母怜、方法:
setRepository(File repository):設(shè)置緩沖區(qū)的大小
setSizeThreshold(int sizeThreshold):設(shè)置臨時文件存放的路徑
3余耽、API的使用的代碼
二、ServletFileUpload:核心解析類
1苹熏、構(gòu)造方法
ServletFileUpload()
ServletFileUpload(FileItemFactory fileItemFactory)
2碟贾、方法
isMultipartContent(HttpServletRequest request)
是用來判斷表單的enctype屬性是否正確
parseRequest(HttpServletRequest request)
解析Request對象,返回一個List集合(每個部分的對象FileItem)
(long fileSizeMax)
用來設(shè)置單個文件的大小
setSizeMax(long sizeMax)
用來設(shè)置上傳的文件的總大小
setHeaderEncoding(String encoding)
用來解決中文文件名上傳的亂碼的問題
setProgressListener(ProgressListener pListener)
設(shè)置監(jiān)聽文件上傳的進度
三轨域、FileItem文件項
1袱耽、方法
isFormField()
判斷表單項是普通項還是文件上傳項,如果為true代表是普通項
2干发、普通項的方法
getFieldName()
用來獲得普通項的名稱
getString()
用來獲取普通項的值
getString(String encoding)
用來獲取普通項的值(可解決亂碼問題)
3朱巨、文件上傳項
getName()
獲得上傳文件的文件名的方法
getInputStream()
獲得上傳文件的文件內(nèi)容的方法
getSize()
獲得上傳文件的文件大小
delete()
刪除文件上傳過程中的臨時文件
(五)JS控制多文件上傳
一、案例需求
? ? 案例需求描述
二枉长、案例實現(xiàn)
? ? 案例代碼實現(xiàn)
(六)文件上傳兼容瀏覽器問題及解決
一冀续、問題描述
? ? 如果使用IE老版本的瀏覽器,會出現(xiàn)一個文件名稱獲取錯誤的問題必峰,因為老版本IE獲取文件名稱的時候洪唐,會帶有路徑
二、問題解決
(七)文件上傳同一個目錄下文件同名的問題及解決
一吼蚁、問題描述
? ? 張三向服務(wù)器上傳了一個文件aa.txt凭需,內(nèi)容是Hello World,李四向服務(wù)器上傳了一個文件aa.txt,內(nèi)容是Hello Java功炮,后上傳的文件將先上傳的文件覆蓋了
二溅潜、問題解決
? ? 使用唯一文件名來解決
(八)文件上傳同一個目錄下存放文件過多的問題及解決
一、問題描述
? ? 現(xiàn)在所有的用戶都上傳文件薪伏,如果網(wǎng)站訪問量比較大滚澜,如果都上傳到同一個目錄下,此目錄下存放的文件太多了嫁怀,也會對程序有影響(在打開該目錄的時候都會很卡设捐,更別說讀寫了,效率會更低)
二塘淑、問題解決
1萝招、目錄分離
按時間分離:按月、周存捺、天槐沼、小時
按用戶分離:按張三、李四
按個數(shù)分離:一個目錄下存放3000個文件
按目錄分離分離算法:按照某種特定算法進行分離
上傳一個文件捌治,得到一個唯一的文件名
獲取唯一文件名的hashCode值——int類型的值(占8個字節(jié)32位)
讓hashCode的值& 0xf;——得出的這個值作為一級目錄
讓hashCode右移4位再 & 0xf;——得出的這個值作為二級目錄
依此類推……
2岗钩、分析算法:
依此類推:共得到8級目錄,每級目錄中又會有從0000-1111的16級子目錄肖油,我們就能得到16的8次方個兼吓,約43億個目錄
3、算法實現(xiàn)