1. 程式人生 > >5.servlet 上傳文件

5.servlet 上傳文件

item 位置 組件 filter err 直接 引入 utf data

一.maven依賴

<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</
groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>

二.DiskFileItemFactory類的使用

將請求消息實體中的每一個項目封裝成單獨的DiskFileItem (FileItem接口的實現) 對象的任務
由 org.apache.commons.fileupload.FileItemFactory 接口的默認實現
org.apache.commons.fileupload.disk.DiskFileItemFactory 來完成。當上傳的文件項目比較小時,直接保存在內存中(速度比較快),比較大時,以臨時文件的形式,保存在磁盤臨時文件夾(雖然速度慢些,但是內存資源是有限的)。

屬性
1) public static final int DEFAULT_SIZE_THRESHOLD :將文件保存在內存還是磁盤臨時文件夾的默認臨界值,值為10240,即10kb。

2) private File repository:用於配置在創建文件項目時,當文件項目大於臨界值時使用的臨時文件夾,默認采用系統默認的臨時文件路徑,可以通過系統屬性 java.io.tmpdir獲取。如下代碼:

System.getProperty("java.io.tmpdir");

3) private int sizeThreshold:用於保存將文件保存在內存還是磁盤臨時文件夾的臨界值

構造方法


1) public DiskFileItemFactory()

采用默認臨界值和系統臨時文件夾構造文件項工廠對象。

2) public DiskFileItemFactory(int sizeThreshold,File repository)

采用參數指定臨界值和系統臨時文件夾構造文件項工廠對象。

3) FileItem createItem()
根據DiskFileItemFactory相關配置將每一個請求消息實體項目創建成DiskFileItem 實例,並返回。該方法從來不需要我們親自調用,FileUpload組件在解析請求時內部使用。

4) void setSizeThreshold(int sizeThreshold)
Apache文件上傳組件在解析上傳數據中的每個字段內容時,需要臨時保存解析出的數據,以便在後面進行數據的進一步處理(保存在磁盤特定位置或插入數據庫)。因為Java虛擬機默認可以使用的內存空間是有限的,超出限制時將會拋出“java.lang.OutOfMemoryError”錯誤。如果上傳的文件很大,例如800M的文件,在內存中將無法臨時保存該文件內容,Apache文件上傳組件轉而采用臨時文件來保存這些數據;但如果上傳的文件很小,例如600個字節的文件,顯然將其直接保存在內存中性能會更加好些。

setSizeThreshold方法用於設置是否將上傳文件已臨時文件的形式保存在磁盤的臨界值(以字節為單位的int值),如果從沒有調用該方法設置此臨界值,將會采用系統默認值10KB。對應的getSizeThreshold() 方法用來獲取此臨界值。

5) void setRepository(File repository)
setRepositoryPath方法用於設置當上傳文件尺寸大於setSizeThreshold方法設置的臨界值時,將文件以臨時文件形式保存在磁盤上的存放目錄。有一個對應的獲得臨時文件夾的 File getRespository() 方法。

註意:當從沒有調用此方法設置臨時文件存儲目錄時,默認采用系統默認的臨時文件路徑,可以通過系統屬性 java.io.tmpdir 獲取。如下代碼:

System.getProperty("java.io.tmpdir");

Tomcat系統默認臨時目錄為“<tomcat安裝目錄>/temp/”。

三.使用Commons-Fileupload包進行大文件上傳註意事項

項目中使用

commons-fileupload-1.2.1.jar

進行大文件上傳。

測試了一把,效果很不錯。

總結如下:

  1. 必須設置好上傳文件的最大閥值

    final long MAX_SIZE = 10 * 1024 * 1024 * 1024;// 設置上傳文件最大為 10G

  2. 必須設置文件上傳服務器上的臨時目錄

    // 文件上傳參數配置
    // 創建一個新的文件上傳句柄
    DiskFileItemFactory factory = new DiskFileItemFactory();
    // 設置內存緩沖區,超過後寫入臨時文件
    factory.setSizeThreshold(4096);
    // 設置上傳到服務器上文件的臨時存放目錄 -- 非常重要,防止存放到系統盤造成系統盤空間不足
    factory.setRepository(new File("F:\\uploadFileTemp"));
    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setHeaderEncoding("utf-8");

    // 設置單個文件的最大上傳值
    upload.setSizeMax(MAX_SIZE); // 文件上傳上限10G

  3. 上傳成功後一定要刪除臨時目錄的臨時文件

    fileItem.delete(); // 請務必調用,在文件上傳結束後,刪除臨時目錄的文件...

  4. 最好記錄下文件從開始上傳到上傳結束的時間點,這個對今後文件上傳時間的分析很有用

另外,因為Struts2的上傳功能也引入了該包,但是卻做了攔截器限制文件的最大上傳大小為2M,可以通過修改它的配置文件動態更改上傳文件的大小;而且,Struts會在文件上傳成功後,幫你刪除掉臨時文件。

我這裏使用的是Spring MVC,需要在上傳類中指定最大上傳文件大小,(這玩意一般不動態設置,最大上傳文件大小一般是系統的標準,是讓使用者遵循滴),而且必須在上傳成功後刪除臨時文件。

5.servlet 上傳文件