FileUpload的學(xué)習(xí)筆記
|
第1次 |
第2次 |
第3次 |
第4次 |
平均 |
Cos |
297 |
203 |
234 |
245 |
245 |
FileUpload |
281 |
312 |
281 |
312 |
297 |
SmartUpload |
531 |
594 |
485 |
532 |
536 |
|
第1次 |
第2次 |
第3次 |
第4次 |
平均 |
Cos |
2562 |
2109 |
2719 |
2172 |
2391 |
FileUpload |
4062 |
4140 |
5360 |
3922 |
4371 |
SmartUpload |
3453 |
3094 |
3078 |
3547 |
3293 |
|
第1次 |
第2次 |
第3次 |
第4次 |
平均 |
|
4860 |
4844 |
5125 |
5171 |
5000 |
FileUpload |
9000 |
8391 |
10375 |
10078 |
9461 |
SmartUpload |
8265 |
9187 |
8672 |
8856 |
8745 |
|
第1次 |
第2次 |
第3次 |
第4次 |
平均 |
Cos |
55813 |
52282 |
54796 |
51187 |
53520 |
FileUpload |
76343 |
68531 |
80954 |
79031 |
76215 |
SmartUpload |
內(nèi)存堆棧溢出 |
|
|
|
|
從上述的表格對比中可以看出Cos始終保持著良好的性能。在上傳量較小(容量<2M,這是最常出現(xiàn)的情況)時,Cos比FileUpload性能并沒有好很多,但SmartUpload就已經(jīng)開始顯出弱勢。
隨著容量的增大,FileUpload和SmartUpload的性能下降非常快,直到200M容量時,SmartUpload已經(jīng)不堪重負(fù)崩潰了,而Cos此時的花費(fèi)時間比FileUpload少了20多秒,不能不說在本次的評測中,Cos的性能位居第一。通過對三種流行的上傳組件進(jìn)行對比,我認(rèn)為選用Cos是比較好的。在實(shí)際的項目中,可以把上傳的文件放到文件夾,文件路徑存于數(shù)據(jù)庫中以便于管理。
如果需要把文件上傳到數(shù)據(jù)庫也很簡單,從Cos中已經(jīng)得到了上傳文件(java.io.File),其后的操作很平常所做的一樣: 通過File得到inputStream,存到數(shù)據(jù)庫的blob或Clob字段即可。
對于使用Struts的項目,我覺得還是使用FileUpload比較好,因為Struts天生集成了FileUpload的功能,使用FileUpload會帶來很多的便利。而如果想要開發(fā)獨(dú)立的上傳組件,則用Cos是最好的選擇,可以在Cos的基礎(chǔ)上封裝一層,暴露給業(yè)務(wù)程序員的只是一些簡單易用的API,而且可以給這些API加上自定義的javaDoc,這對于實(shí)際的開發(fā)和將來的擴(kuò)展都是非常方便的。下面對FileUpload的上傳機(jī)制作一些分析,基本上,上傳一個文件的過程在FileUpload中可以分為三個部分:
1.由客戶端把要上傳的文件生成request數(shù)據(jù)流,與服務(wù)器端建立連接
2.在服務(wù)器端接收request流,將流緩存到內(nèi)存或磁盤中(具體緩存到什么地方,將由DiskFileUpload的setSizeThreshold(int cacheMax)方法來決定,當(dāng)文件大小<cacheMax時,文件將被緩存到內(nèi)存,否則將被緩存到磁盤的臨時文件)
3.由服務(wù)器端的內(nèi)存或是臨時文件中把文件輸出到指定的目錄(這個目錄才是指定的文件上傳目錄).
上述的第一步由瀏覽器完成,不用過多理會,重點(diǎn)是第二和第三步。
第二步時,由DiskFileUpload的parseRequest(...)方法(其實(shí)這個方法是繼承于FileUploadBase類,真正起解析request流作用的類是FileUploadBase)解析request流。在parseRequest(...)方法中,新建了一個MultipartStream實(shí)例,由此實(shí)例的readBodyData()方法將上傳文件的流讀到FileItem實(shí)例中,F(xiàn)ileItem實(shí)例根據(jù)設(shè)置好的cacheMax大小,引用一個內(nèi)存中的數(shù)據(jù)流或是一個磁盤上的數(shù)據(jù)流,注意此時文件已經(jīng)上傳到了服務(wù)器,但仍然沒有傳到設(shè)定的上傳目錄。
第三步時,調(diào)用FileItem實(shí)例的write(File file)方法,將已經(jīng)存在于內(nèi)存或是磁盤上的上傳文件流拷貝到設(shè)定好的上傳目錄,至此上傳仍未結(jié)束,因為磁盤中很可能保存了上傳文件的臨時文件(當(dāng)設(shè)定的cacheMax<文件大小時),如何刪除這些臨時文件?有兩種方法:1.顯示調(diào)用FileItem實(shí)例的delete()方法。2.不調(diào)用任何方法,當(dāng)FileItem被垃圾回收時,由finalize()方法刪除臨時文件。