Java 文件上傳處理庫,Fastupload 0.5.3 發布
相對于以往的版本,fastupload 0.5.3做出了明顯的增強和修改。此版本中,“融合“了磁盤解析方式和內存解析方式,磁盤解析方式也支持非文件類型輸入的解析,減少了磁盤解析模式中 UploadChunk對象的創建,提升了解析性能,改進了字符編碼轉換,API更加簡明。
基本API使用
默認情況下,fastupload建議使用內存解析模式,因為這種模式下解析的性能是最好的,而且,解析出的數據是在內存中,很容易處理。其API使用如下,
FastUploadParser fastUploadParser = new FastUploadParser(request); List<MultiPart> list = fastUploadParser.parseList(); for (MultiPart e: list){ if (e.isFile()){ System.out.format("input field name: %s, file name:%s%n", e.getFieldName(), e.getFileName()); e.toFile( /file/ ) ; //write data to a file where you want to place } else { System.out.format("input field name: %s, value:%s%n", e.getFieldName(), e.getString()); } }
但是在某些特定的情況下,比如對內存的使用限制要求強烈的場合,或者上傳的文件非常大,可以使用磁盤解析模式,這種模式下,API的使用與內存模式基本相同,只不過需要創建FileFactory對象,并把這個對象作為FastUploadParser構造函數的第二個參數。
FileFactory fileFactory = FileFactory.getInstance(); fileFactory.setRepository(System.getProperty("user.home")+"/fastupload"); FastUploadParser fastUploadParser = new FastUploadParser(request, fileFactory); List<MultiPart> list = fastUploadParser.parseList(); for (MultiPart e: list){ if (e.isFile()){ System.out.format("input field name: %s, file name:%s%n", e.getFieldName(), e.getFileName()); e.toFile( /target/ ) ; //move temporary file to where you want to place } else { System.out.format("input field name: %s, value:%s%n", e.getFieldName(), e.getString()); } }
在這種模式下,當從multipart/form-data輸入流中發現有上傳的文件時,會在FileFactory指定的目錄內創建一個臨時文件,每次寫入不超過8k的數據,此文件的數據分析完后,關閉文件。因此,要使用e.toFile(...) 函數把這個臨時文件移至你所想要的地方,對于非文件類型的輸入,e.getString()輸出其內容。
高級特性
有時候,需要限制客戶端上傳的文件,不同于其他的文件解析組建,Fastupload采用預先特性匹配機制,在解析過程中,一旦發現頭信息與設定的模式不匹配時,會自動跳過此部分。API使用如下
FileFactory fileFactory = FileFactory.getInstance(); fileFactory.setAllowedTypes("image/jpeg"); fileFactory.setAllowedExtensions(".jpg, .png");
當然,文件大小的限制,也是必須要支持的,下面的第一行代碼是設定每個文件不超過200000字節,第二行代碼是設定multipart輸入流的總大小不超過2000000字節,注意,這里的總數是包含一些HTML的代碼在內的
fileFactory.setThreshold(200000); fileFactory.setMaxContentLength(2000000);
如果想知道解析的進度,可以創建一個ProgressListener對象
ProgressListener listener = new ProgressListener(fastUploadParser); listener.progress();
字符編碼
java語言本身是支持unicode的,并且,在各種unicode之間進行轉換是很容易的,但是比較杯具的是,在Servlet規范中,沒有規定檢測傳輸的數據所采用的編碼方法,在服端編程時,沒有調用ServletRequest.setCharsetEncoding(...) 函數時,ServletRequest.getCharsetEncoding(...) 函數永遠返回null,在程序里,很難知道客戶端發送過來的數據流是采用以什么字符集進行編碼的。不僅如此,即使知道了數據流編碼所采用的字符集,可能和運行著的Servlet容器所使用的字符集不一樣,可能和操作系統所使用的字符集也不一樣,因此對數據流進行適當的字符集轉換,并按照Servlet容器所使用的字符保存到文件系統,對于防范由字符編碼引起的問題。
在unicode環境中,首先要告訴ServletRequest,客戶端發送數據時編碼所采用的字符集,給FileFactory設置目標字符集,如果不想顯式初始化帶有編碼的FileFactory對象,可以在啟動JVM時加上 -Dfile.encoding="UTF-8"參數,FileFactory會取這個默認的字符集。
request.setCharsetEncoding(“gbk"); FileFactory fileFactory = FileFactory.getInstance("utf-8"); // ... 以下省略解析代碼
對于磁盤解析方式,正確的設定了ServletRequest編碼字符集和目標字符集后,文本文件可以進行正確的轉碼。有一點需要注意的是,即使是文本文件,瀏覽器按照二進制流的形式把其內容“灌入”到HTTP流中,當對其文件名卻按照瀏覽器當前的字符集進行編碼,假如文本文件保存的時候,編碼是 gbk,用瀏覽器上傳文件時選用了utf8,這樣,fastupload就不能正確的進行轉碼工作。因此在磁盤解析模式下,有必要讓瀏覽器采用和操作系統同樣的編碼。
而對于內存解析方式,API使用者代碼可以直接訪問到二進制的流,可以隨心所欲的進行編碼轉換工作。
1, MultiPart part ...; 2, part.getString(); 3, part.getString("gbk");
這個代碼片段中,第二行是對解析到的流按照系統默認的字符集轉換成String,第三行是按照指定的字符集對字節流進行編碼,轉換成String。
@儀山湖
項目地址:https://sourceforge.net/projects/fastupload/
項目wiki: https://sourceforge.net/p/fastupload/wiki/Fastupload%20Home/