日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Apache FileUpload介绍

發(fā)布時(shí)間:2025/3/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Apache FileUpload介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Apache FileUpload組件

在最初的 http 協(xié)議中,沒有上傳文件方面的功能。RFC1867(“Form-based File Upload in HTML”.)為 http 協(xié)議添加了這個(gè)功能。客戶端的瀏覽器,如 Microsoft IE, Mozila, Opera 等,按照此規(guī)范將用戶指定的文件發(fā)送到服務(wù)器。服務(wù)器端的網(wǎng)頁程序,如 php, asp, jsp 等,可以按照此規(guī)范,解析出用戶發(fā)送來的文件。

1.1、客戶端

簡單來說,RFC1867規(guī)范要求http協(xié)議增加了file類型的input標(biāo)簽,用于瀏覽需要上傳的文件。同時(shí)要求FORM表單的enctype屬性設(shè)置為“multipart/form-data”,method屬性設(shè)置為“post”即可,下面是我們文。
件上傳頁面的表單代碼:

<form action="<%=request.getContextPath()%>/Upload3Servlet" method="post" enctype="multipart/form-data"> File1:<input type="file" name="file"/><br/> Desc:<input type="text" name="desc"/><br/> <input type="submit" value="提交"/> </form>

1.2、服務(wù)器端
一個(gè)文件上傳請(qǐng)求的消息實(shí)體由一系列根據(jù) RFC1867(“Form-based File Upload in HTML”.)編碼的項(xiàng)目(文本參數(shù)和文件參數(shù))組成。自己編程來解析獲取這些數(shù)據(jù)是非常麻煩的,還需要了解RFC1867規(guī)范對(duì)請(qǐng)求數(shù)據(jù)編碼的相關(guān)知識(shí)。FileUpload 可以幫助我們解析這樣的請(qǐng)求,將每一個(gè)項(xiàng)目封裝成一個(gè)實(shí)現(xiàn)了FileItem接口的對(duì)象,并以列表的形式返回。所以,我們只需要了解FileUpload的API如何使用即可,不用管它們的底層實(shí)現(xiàn)。
讓我們來看一個(gè)簡單文件上傳處理代碼:

package cn.itcast.servlet; import java.io.File; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; /*** 文件上傳* @author <a href="mailto:wj@itcast.cn">王健</a>*/ public class UploadServlet extends HttpServlet { @SuppressWarnings("unchecked") public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { DiskFileItemFactory f = new DiskFileItemFactory();//磁盤對(duì)象 f.setRepository(new File("d:/a")); //設(shè)置臨時(shí)目錄 f.setSizeThreshold(1024*8); //8k的緩沖區(qū),文件大于8K則保存到臨時(shí)目錄 ServletFileUpload upload = new ServletFileUpload(f);//聲明解析request的對(duì)象 upload.setHeaderEncoding("UTF-8"); //處理文件名中文 upload.setFileSizeMax(1024 * 1024 * 5);// 設(shè)置每個(gè)文件最大為5M upload.setSizeMax(1024 * 1024 * 10);// 一共最多能上傳10M String path = getServletContext().getRealPath("/imgs");//獲取文件要保存的目錄 try { List<FileItem> list = upload.parseRequest(request);// 解析 for (FileItem ff : list) { if (ff.isFormField()) { String ds = ff.getString("UTF-8");//處理中文 System.err.println("說明是:" + ds); } else { String ss = ff.getName(); ss = ss.substring(ss.lastIndexOf("\\") + 1);//解析文件名 FileUtils.copyInputStreamToFile( //直接使用commons.io.FileUtils ff.getInputStream(), new File(path + "/" + ss)); } } } catch (Exception e) { e.printStackTrace(); } } }

1.3、FileItem接口
org.apache.commons.fileupload.disk.DiskFileItem實(shí)現(xiàn)了FileItem接口,用來封裝單個(gè)表單字段元素的數(shù)據(jù)。通過調(diào)用FileItem 定義的方法可以獲得相關(guān)表單字段元素的數(shù)據(jù)。我們不需要關(guān)心DiskFileItem的具體實(shí)現(xiàn),在程序中可以采用FileItem接口類型來對(duì)DiskFileItem對(duì)象進(jìn)行引用和訪問。FileItem類還實(shí)現(xiàn)了Serializable接口,以支持序列化操作。

FileItem類常用的方法:

1. boolean isFormField()方法
isFormField方法用于判斷FileItem類對(duì)象封裝的數(shù)據(jù)是一個(gè)普通文本表單字段,還是一個(gè)文件表單字段,如果是普通表單字段則返回true,否則返回false。

2. String getName()方法

getName方法用于獲得文件上傳字段中的文件名,即表單字段元素描述頭中的filename屬性值,如“C:\Documents and Settings\All Users\Documents\My Pictures\示例圖片\Sunset.jpg”。如果FileItem類對(duì)象對(duì)應(yīng)的是普通表單字段,getName方法將返回null。即使用戶沒有通過網(wǎng)頁表單中的文件字段傳遞任何
文件,但只要設(shè)置了文件表單字段的name屬性,瀏覽器也會(huì)將文件字段的信息傳遞給服務(wù)器,只是文件名和文件內(nèi)容部分都為空,但這個(gè)表單字段仍然對(duì)應(yīng)一個(gè)FileItem對(duì)象,此時(shí),getName方法返回結(jié)果為空字符串"",讀者在調(diào)用Apache文件上傳組件時(shí)要注意考慮這個(gè)情況。
注意:上面的數(shù)據(jù)包是通過IE提交,所以是完整的路徑和名稱。如
C:\Documents and Settings\All Users\Documents\My Pictures\示例圖片\Sunset.jpg。如果是其它瀏覽器,如火狐和Chromium,則僅僅是名字,沒有路徑,如Sunset.jpg。

3. String getFieldName()方法
getFieldName方法用于返回表單字段元素描述頭的name屬性值,也是表單標(biāo)簽name屬性的值。例如“name=file1”中的“file1”。

4. void write(File file)方法
write方法用于將FileItem對(duì)象中保存的主體內(nèi)容保存到某個(gè)指定的文件中。如果FileItem對(duì)象中的主體內(nèi)容是保存在某個(gè)臨時(shí)文件中,該方法順利完成后,臨時(shí)文件有可能會(huì)被清除。該方法也可將普通表單字段內(nèi)容寫入到一個(gè)文件中,但它主要用途是將上傳的文件內(nèi)容保存在本地文件系統(tǒng)中。

5. String getString()方法
getString方法用于將FileItem對(duì)象中保存的數(shù)據(jù)流內(nèi)容以一個(gè)字符串返回,它有兩個(gè)重載的定義形式:
public java.lang.String getString()
public java.lang.String getString(java.lang.String encoding) throws java.io.UnsupportedEncodingException
前者使用缺省的字符集編碼將主體內(nèi)容轉(zhuǎn)換成字符串,后者使用參數(shù)指定的字符集編碼將主體內(nèi)容轉(zhuǎn)換成字符串。如果在讀取普通表單字段元素的內(nèi)容時(shí)出現(xiàn)了中文亂碼現(xiàn)象,請(qǐng)調(diào)用第二個(gè)getString方法,并為之傳遞正確的字符集編碼名稱。

6. String getContentType()方法
getContentType 方法用于獲得上傳文件的類型,即表單字段元素描述頭屬性“Content-Type”的值,如“image/jpeg”。如果FileItem類對(duì)象對(duì)應(yīng)的是普通表單字段,該方法將返回null。

7. boolean isInMemory()方法
isInMemory方法用來判斷FileItem對(duì)象封裝的數(shù)據(jù)內(nèi)容是存儲(chǔ)在內(nèi)存中,還是存儲(chǔ)在臨時(shí)文件中,如果存儲(chǔ)在內(nèi)存中則返回true,否則返回false。

8. void delete()方法
delete方法用來清空FileItem類對(duì)象中存放的主體內(nèi)容,如果主體內(nèi)容被保存在臨時(shí)文件中,delete方法將刪除該臨時(shí)文件。盡管當(dāng)FileItem對(duì)象被垃圾收集器收集時(shí)會(huì)自動(dòng)清除臨時(shí)文件,但及時(shí)調(diào)用delete方法可以更早的清除臨時(shí)文件,釋放系統(tǒng)存儲(chǔ)資源。另外,當(dāng)系統(tǒng)出現(xiàn)異常時(shí),仍有可能造成有的臨時(shí)文件被永久保存在了硬盤中。

9. InputStream getInputStream()方法
以流的形式返回上傳文件的數(shù)據(jù)內(nèi)容。

10. long getSize()方法
返回該上傳文件的大小(以字節(jié)為單位)。

1.4、DiskFileItemFactory

此類將請(qǐng)求消息實(shí)體中的每一個(gè)項(xiàng)目封裝成單獨(dú)的DiskFileItem (FileItem接口的實(shí)現(xiàn)) 對(duì)象的任務(wù)由 org.apache.commons.fileupload.FileItemFactory 接口的默認(rèn)實(shí)現(xiàn) org.apache.commons.fileupload.disk.DiskFileItemFactory 來完成。當(dāng)上傳的文件項(xiàng)目比較小時(shí),直接保存在內(nèi)存中(速度比較快),比較大時(shí),以臨時(shí)文件的形式,保存在磁盤臨時(shí)文件夾(雖然速度慢些,但是內(nèi)存資源是有限的)。
屬性:
1) public static final int DEFAULT_SIZE_THRESHOLD :
將文件保存在內(nèi)存還是磁盤臨時(shí)文件夾的默認(rèn)臨界值,值為10240,即10kb。

2) private File repository:
用于配置在創(chuàng)建文件項(xiàng)目時(shí),當(dāng)文件項(xiàng)目大于臨界值時(shí)使用的臨時(shí)文件夾,默認(rèn)采用系統(tǒng)默認(rèn)的臨時(shí)文件路徑,可以通過系統(tǒng)屬性 java.io.tmpdir
獲取。代碼:System.getProperty(“java.io.tmpdir”);

3) private int sizeThreshold:
用于保存將文件保存在內(nèi)存還是磁盤臨時(shí)文件夾的臨界值。

構(gòu)造方法:

1) public DiskFileItemFactory():
采用默認(rèn)臨界值和系統(tǒng)臨時(shí)文件夾構(gòu)造文件項(xiàng)工廠對(duì)象。
2) public DiskFileItemFactory(int sizeThreshold,File repository):
采用參數(shù)指定臨界值和系統(tǒng)臨時(shí)文件夾構(gòu)造文件項(xiàng)工廠對(duì)象。

其他方法:
1、FileItem createItem() 方法
根據(jù)DiskFileItemFactory相關(guān)配置將每一個(gè)請(qǐng)求消息實(shí)體項(xiàng)目創(chuàng)建 成DiskFileItem 實(shí)例,并返回。該方法從來不需要我們親自調(diào)用,FileUpload組件在解析請(qǐng)求時(shí)內(nèi)部使用。

2、void setSizeThreshold(int sizeThreshold)
Apache文件上傳組件在解析上傳數(shù)據(jù)中的每個(gè)字段內(nèi)容時(shí),需要臨時(shí)保存解析出的數(shù)據(jù),以便在后面進(jìn)行數(shù)據(jù)的進(jìn)一步處理(保存在磁盤特定位置或插入數(shù)據(jù)庫)。因?yàn)镴ava虛擬機(jī)默認(rèn)可以使用的內(nèi)存空間是有限的,超出限制時(shí)將會(huì)拋出“java.lang.OutOfMemoryError”錯(cuò)誤。如果上傳的文件
很大,例如800M的文件,在內(nèi)存中將無法臨時(shí)保存該文件內(nèi)容,Apache文件上傳組件轉(zhuǎn)而采用臨時(shí)文件來保存這些數(shù)據(jù);但如果上傳的文件很小,例如600個(gè)字節(jié)的文件,顯然將其直接保存在內(nèi)存中性能會(huì)更加好些。

3、setSizeThreshold
方法用于設(shè)置是否將上傳文件已臨時(shí)文件的形式保存在磁盤的臨界值(以字節(jié)為單位的int值),如果從沒有調(diào)用該方法設(shè)置此臨界值,將會(huì)采用系統(tǒng)默認(rèn)值10KB。對(duì)應(yīng)的getSizeThreshold() 方法用來獲取此臨界值。

4、void setRepository(File repository)
setRepositoryPath方法用于設(shè)置當(dāng)上傳文件尺寸大于setSizeThreshold方法設(shè)置的臨界值時(shí),將文件以臨時(shí)文件形式保存在磁盤上的存放目錄。有一個(gè)對(duì)應(yīng)的獲得臨時(shí)文件夾的 File getRespository() 方法。
注意:當(dāng)從沒有調(diào)用此方法設(shè)置臨時(shí)文件存儲(chǔ)目錄時(shí),默認(rèn)采用系統(tǒng)默認(rèn)的臨時(shí)文件路徑,可以通過系統(tǒng)屬性 java.io.tmpdir 獲取。
如下代碼:
System.getProperty(“java.io.tmpdir”);
Tomcat系統(tǒng)默認(rèn)臨時(shí)目錄為“<tomcat安裝目錄>/temp/”。

說明:
使用List list = servletFileUpload.parseRequest(httpServletRequest);方法,則臨時(shí)目錄受用戶設(shè)置的管理。即,如果用戶設(shè)置的臨時(shí)目錄為d:/a,則當(dāng)文件上傳大于,大于緩沖區(qū)設(shè)置時(shí)會(huì)向d:/a下保存臨時(shí)文件。如果用戶沒有設(shè)置臨時(shí)目錄,才會(huì)將臨時(shí)文件保存到CATALINA_HOME\temp目錄下。
此種方式保存的臨時(shí)文件名為:upload_2eb46fea_13615ef5327__8000_00000000.tmp
使用FileItemIterator fii = servletFileUpload.getItemIterator(httpServletRequest)方法時(shí),則不受用戶設(shè)置臨時(shí)目錄的影響。總是會(huì)將文件保臨時(shí)文件保存到CATALINA_HOME\temp目錄下。
此種情況下保存的臨時(shí)文件名為:hsperfdata_Administrator (這是一個(gè)文件夾,用里面的文件做為數(shù)據(jù)交互)
圖示:

1.5、ServletFileUpload類
org.apache.commons.fileupload.servlet.ServletFileUpload類是Apache文件上傳組件處理文件上傳的核心高級(jí)類(所謂高級(jí)就是不需要管底層實(shí)現(xiàn),暴露給用戶的簡單易用的接口)。使用其 parseRequest(HttpServletRequest) 方法可以將通過表單中每一個(gè)HTML標(biāo)簽提交的數(shù)據(jù)封裝成一個(gè)FileItem對(duì)象,然后以List列表的形式返回。使用該方法處理上傳文件簡單易用。
如果你希望進(jìn)一步提高性能,你可以采用 getItemIterator 方法,直接獲得每一個(gè)文件項(xiàng)的數(shù)據(jù)輸入流,對(duì)數(shù)據(jù)做直接處理。
在使用ServletFileUpload對(duì)象解析請(qǐng)求時(shí)需要根據(jù)DiskFileItemFactory對(duì)象的屬性 sizeThreshold(臨界值)和repository(臨時(shí)目錄) 來決定將解析得到的數(shù)據(jù)保存在內(nèi)存還是臨時(shí)文件中,如果是臨時(shí)文件,保存在哪個(gè)臨時(shí)目錄中?。所以,我們需要在進(jìn)行解析工作前構(gòu)造好DiskFileItemFactory對(duì)象,
通過ServletFileUpload對(duì)象的構(gòu)造方法或setFileItemFactory()方法設(shè)置 ServletFileUpload對(duì)象的fileItemFactory屬性。
ServletFileUpload的繼承結(jié)構(gòu)為:

構(gòu)造方法:

1) public ServletFileUpload():
構(gòu)造一個(gè)未初始化的實(shí)例,需要在解析請(qǐng)求之前先調(diào)用setFileItemFactory()方法設(shè)置 fileItemFactory屬性。

2) public ServletFileUpload(FileItemFactory fileItemFactory):
構(gòu)造一個(gè)實(shí)例,并根據(jù)參數(shù)指定的FileItemFactory 對(duì)象,設(shè)置 fileItemFactory屬性。

ServletFileUpload類常用方法:

1. public void setSizeMax(long sizeMax)
方法setSizeMax方法繼承自FileUploadBase類,用于設(shè)置請(qǐng)求消息實(shí)體內(nèi)容(即所有上傳數(shù)據(jù))的最大尺寸限制,以防止客戶端惡意上傳超大文件來浪費(fèi)服務(wù)器端的存儲(chǔ)空間。其參數(shù)是以字節(jié)為單位的long型數(shù)字。
在請(qǐng)求解析的過程中,如果請(qǐng)求消息體內(nèi)容的大小超過了setSizeMax方法的設(shè)置值,將會(huì)拋出FileUploadBase內(nèi)部定義的SizeLimitExceededException異常(FileUploadException的子類)。
如:
org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException:
the request was rejected because its size (1649104) exceeds the configured
maximum (153600)
該方法有一個(gè)對(duì)應(yīng)的讀方法:public long getSizeMax()方法。

2. public void setFileSizeMax(long fileSizeMax)
方法setFileSizeMax方法繼承自FileUploadBase類,用于設(shè)置單個(gè)上傳文件的最大尺寸限制,以防止客戶端惡意上傳超大文件來浪費(fèi)服務(wù)器端的存儲(chǔ)空間。其參數(shù)是以字節(jié)為單位的long型數(shù)字。該方法有一個(gè)對(duì)應(yīng)的讀方法:public long geFileSizeMax()方法。
在請(qǐng)求解析的過程中,如果單個(gè)上傳文件的大小超過了setFileSizeMax方法的設(shè)置值,將會(huì)拋出FileUploadBase內(nèi)部定義的FileSizeLimitExceededException異常(FileUploadException的子類)。
如:
org.apache.commons.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file1 exceeds its
maximum permitted size of 51200 characters.

3. public List parseRequest(javax.servlet.http.HttpServletRequest req)
parseRequest 方法是ServletFileUpload類的重要方法,它是對(duì)HTTP請(qǐng)求消息體內(nèi)容進(jìn)行解析的入口方法。它解析出FORM表單中的每個(gè)字段的數(shù)據(jù),并將它們分別包裝成獨(dú)立的FileItem對(duì)象,然后將這些FileItem對(duì)象加入進(jìn)一個(gè)List類型的集合對(duì)象中返回。
該方法拋出FileUploadException異常來處理諸如文件尺寸過大、請(qǐng)求消息中的實(shí)體內(nèi)容的類型不是“multipart/form-data”、IO異常、請(qǐng)求消息體長度信息丟失等各種異常。每一種異常都是FileUploadException的一個(gè)子類型。

4. public FileItemIterator getItemIterator(HttpServletRequest request)
getItemIterator方法和parseRequest 方法基本相同。但是getItemIterator方法返回的是一個(gè)迭代器,該迭代器中保存的不是FileItem對(duì)象,而是FileItemStream 對(duì)象,如果你希望進(jìn)一步提高性能,你可以采用 getItemIterator 方法,直接獲得每一個(gè)文件項(xiàng)的數(shù)據(jù)輸入流,做底層處理;如果性能不
是問題,你希望代碼簡單,則采用parseRequest方法即可。

5. public stiatc boolean isMultipartContent(HttpServletRequest req)
isMultipartContent方法方法用于判斷請(qǐng)求消息中的內(nèi)容是否是“multipart/form-data”類型,是則返回true,否則返回false。isMultipartContent方法是一個(gè)靜態(tài)方法,不用創(chuàng)建ServletFileUpload類的實(shí)例對(duì)象即可被調(diào)用。

6. getFileItemFactory()和setFileItemFactory(FileItemFactory)
兩個(gè)方法繼承自FileUpload類,用于設(shè)置和讀取fileItemFactory屬性。

7. public void setProgressListener(ProgressListener pListener)
設(shè)置文件上傳進(jìn)度監(jiān)聽器。該方法有一個(gè)對(duì)應(yīng)的讀取方法:ProgressListener getProgressListener()。

8.public void setHeaderEncoding()方法
在文件上傳請(qǐng)求的消息體中,除了普通表單域的值是文本內(nèi)容以外,文件上傳字段中的文件路徑名也是文本,在內(nèi)存中保存的是它們的某種字符集編碼的字節(jié)數(shù)組,Apache文件上傳組件在讀取這些內(nèi)容時(shí),必須知道它們所采用的字符集編碼,才能將它們轉(zhuǎn)換成正確的字符文本返回。
setHeaderEncoding方法繼承自FileUploadBase類,用于設(shè)置上面提到的字符編碼。如果沒有設(shè)置,則對(duì)應(yīng)的讀方法getHeaderEncoding()方法返回null,將采用HttpServletRequest設(shè)置的字符編碼,如果HttpServletRequest的字符編碼也為null,則采用系統(tǒng)默認(rèn)字符編碼。可以通過一下語句獲得系統(tǒng)默認(rèn)字符編碼:
System.getProperty(“file.encoding”));

1.6、FileItemStream性能提升
以下是使用FileItemStream三次上傳一個(gè)70M文件的時(shí)間:
文件名為:電影.avi
Desc:這是信息
用時(shí):1516
文件名為:電影.avi
Desc:這是信息
用時(shí):703
文件名為:電影.avi
Desc:這是信息
用時(shí):656
對(duì)比:
以下是用FileItem三次上傳一個(gè)70M文件的時(shí)間:
文件名為:電影.avi
說明是:這是信息
用時(shí):1687
文件名為:電影.avi
說明是:這是信息
用時(shí):2578
文件名為:電影.avi
說明是:這是信息
用時(shí):2297
可見:FileItemSteam(servletFileUpload.getItemIterator(httpServletRequest))速度要快于FileItem(servletFileUpload.parseRequest(request))速度。且一般情況下,FileItemSteam不產(chǎn)生臨時(shí)文件:
源代碼:

package cn.itcast.servlet; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Scanner; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; /*** FileItemStream示例* @author <a href="mailto:wj@itcast.cn">王健</a>* @version 1.0 2012-3-15*/ public class Upload3Servlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { long start = System.currentTimeMillis(); String path = getServletContext().getRealPath("/imgs"); DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024 * 8);// 設(shè)置8k的緩存空間 factory.setRepository(new File("d:/a")); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8");// 設(shè)置文件名處理中文編碼 try { FileItemIterator fii = upload.getItemIterator(request);// 使用遍歷類 while (fii.hasNext()) { FileItemStream fis = fii.next(); if (fis.isFormField()) {//FileItemStream同樣使用OpenStream獲取普通表單的值 InputStreamReader in = new InputStreamReader(fis.openStream(),"UTF-8"); Scanner sc = new Scanner(in); StringBuffer sb = new StringBuffer(); if(sc.hasNextLine()){ sb.append(sc.nextLine()); } System.err.println("Desc:"+sb.toString()); } else { String fileName = fis.getName(); fileName = fileName .substring(fileName.lastIndexOf("\\") + 1); System.err.println("文件名為:" + fileName); InputStream in = fis.openStream(); FileUtils.copyInputStreamToFile(in, new File(path+"/"+fileName)); } } } catch (FileUploadException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.err.println("用時(shí):"+(end-start)); } }

1.7、FileCleanerCleanup清理資源

只適用于你使用 DiskFileItem 的情況.換句話說,就是在你處理上傳的數(shù)據(jù)之前它們被存放在臨時(shí)文件中。 這些臨時(shí)文件在不再被使用的時(shí)候(如果相應(yīng)的java.io.File是可回收的則更好)會(huì)自動(dòng)被刪除.這會(huì)被org.apache.commons.io.FileCleaningTracker的一個(gè)實(shí)例啟動(dòng)的一個(gè)收割線程默默執(zhí)行。

你的web應(yīng)用應(yīng)該使用org.apache.commons.fileupload.FileCleanerCleanup的一個(gè)實(shí)例.那很簡單,你只要把它加到你的 web.xml 中:

<listener><listener-class>org.apache.commons.fileupload.servlet.FileCleanerCleanup</listener-class></listener>

然后,在創(chuàng)建了DiskFileItemFactory以后,設(shè)置資源回收:
DiskFileItemFactory f = new DiskFileItemFactory();//聲明臨時(shí)文件對(duì)象
f.setFileCleaningTracker(FileCleanerCleanup.getFileCleaningTracker(this.getServletContext()));
f.setSizeThreshold(1024*8);
//設(shè)置在內(nèi)存中最多可以放多少個(gè)字節(jié),如果超出這個(gè)字節(jié),保存到臨文件中去
f.setRepository(new File(“d:/a”));
//設(shè)置臨時(shí)目錄

注意:必須要正常關(guān)閉Tomcat服務(wù)器。因?yàn)榇司€程在tomcat終止時(shí)會(huì)調(diào)用清空臨時(shí)文件的代碼。
正常關(guān)閉,是指執(zhí)行CATALINA_HOME\bin\shutdown.bat文件。

1.8、進(jìn)度ProgressListener
這個(gè)進(jìn)度條比較合適于在后臺(tái)監(jiān)控進(jìn)度,如果在作上傳進(jìn)度,還是使用ajax更加合適:
示例代碼:

upload.setProgressListener(new ProgressListener() { double dd = 0; long len = 0; //參數(shù)1:已經(jīng)上傳完成的數(shù)量 //參數(shù)2:總長度 //參數(shù)3:第幾個(gè)元素從1開始。0為沒有 public void update(long pBytesRead, long pContentLength, int pItems) { double persent = pBytesRead*100/pContentLength; if(dd!=persent){ System.err.println(dd+"%"); dd=persent; }else if(persent==100){ System.err.println("100%"); } } });

總結(jié)

以上是生活随笔為你收集整理的Apache FileUpload介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。