Java文件上傳組件:Fastupload API快速上手
fastupload提供兩種從multipart/form-data表單請求數據中解析文件的方法,直接法和批量法
直接法:
是fastupload提供的第一種解析方法,從HttpServletRequest的InputStream中每次讀取不超過8K的數據到緩沖區之中,從這個緩沖區里解析是否有文件,或者是文件的一部分數據,把每次解析的結果“直接 ”保存到磁盤文件中去。fastupload最先實現的是這種方式,這種方式一個好處就是對內存的占用非常小,解析內容的緩沖只有8K。因此非常適合那種 對內存要求很苛刻的應用場景,而且解析的速度也非常快,這里有幾組比較數據,可以參考一下,http://mojarra.iteye.com/blog /1581521, http://mojarra.iteye.com/blog/1579986
具體的API使用如下
DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home")); DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home") , "utf-8"); DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home") , "utf-8", 0x20000); dff.setParseThreshold(0x100000); HttpFileUploadParser parser = new HttpFileUploadParser(req, dff); List<MultiPartFile> files = parser.parse();
在解析文件之前,需要創建DiskFileFactory工廠,用來指定解析時用來的一些必要的“數據”,DiskFileFactory有三種構造函數,
第一種,創建DiskFileFactory工廠,文件保存在用戶home目錄下,使用jdk默認的文件編碼,無文件大小限制
第二種,創建DiskFileFactory工廠,文件保存在用戶home目錄下,使用utf-8編碼,無文件大小限制
第三種,創建DiskFileFactory工廠,文件保存在用戶home目錄下,使用utf-8編碼,文件大小限制在0x20000
上面的列子中,第四行代碼可以和這三個構造函數配合使用,來限制整個請求的數據的大小,如果指定 了整個請求數據的大小,即指定了ParseThreshold的值,類HttpFileUploadParser在解析文件之前,先和 HttpServletRequest的Content-Length相比較,如果發現ParseThreshold>Content- Length,直接拋出ThresholdException異常。
這里稍微提醒一下,因為HTTP協議的規定,HTTP請求的Content-Length會比上傳文件的實際字節數稍微大一點。
上面代碼的第五、六行,創建HttpFileUploadParser對象,并解析文件。如果指定了字符編碼,解析過程中把文件名轉換成所指定的字符編碼,除此之外,若解析過程發現了文本文件,也會對文件的內容進行轉碼。
批量法:
fastupload提供的第二種解析方式,是把HttpServletRequest的 InputStream中所有的數據都讀取到一片大的緩沖區中(相對于第一種方式種所采用的8K緩沖區,不知道要大多少倍的),再從這片大的緩沖區中,解 析multipart/form-data數據中的文件或者其他輸入內容。解析出來的數據通過MultiPartData類中提供的一些API,讓API 使用者可以對這些數據進行操作。
因為是把HttpServletRequest的InputStream中所有的數據讀入緩沖后,做一次解析的,所以批量法解析的速度是非常快的,比第一種要快3倍以上,因此,批量法非常適合那種對速度相應要快,不太介意內存使用、高并發上傳小文件的場合。
這里與直接法有些不同,批量法除了支持解析文件外,還支持解析multipart/form-data中非文件的上傳數據,比如表單中的文本輸入框中用戶手工的輸入數據。
MultiPartDataFactory mpdf = new MemoryMultiPartDataFactory(); MultiPartDataFactory mpdf = new MemoryMultiPartDataFactory("utf-8"); MultiPartDataFactory mpdf = new MemoryMultiPartDataFactory("utf-8", 0x20000); mpdf.setParseThreshold(0x100000); HttpMemoryUploadParser httpMemoryUploadParser = new HttpMemoryUploadParser( request, mpdf); List<MultiPartData> list = httpMemoryUploadParser.parseList(); for (MultiPartData e : list) { String target = String.format("%s/%s", dir.getAbsolutePath(), e.getFileName()); if (e.isFile()) { e.toFile(target); } else { if (e.getBytes() > 0) System.out.println(new String(e.getContentBuffer())); } }
創建MemoryMultiPartDataFactory 與創建DiskFileFactory基本相同,只不過少了一個path參數,(確實,內存中的數據不需要path ),編碼、文件大小限制,解析總長度與DiskFileFactory都起著一樣的作用,這里不在復述。
經過httpMemoryUploadParser解析出的multipart/form- data表單中的各部分內容,都會保存在一個包含MultiPartData對象的數組之中,API使用者可以MultiPartData類封裝的幾個與 上傳內容重點相關的函數來訪問解析的內容。
- MultiPartData.getName(), 返回表單中輸入控件的名字,如<intput type="text" name="text1"/>,那么此函數返回text1。
- MultiPartData.getFileName(),返回表單中文件輸入控件的文件名字,如用戶在某文件輸入框中選擇了名為“my cat.jpg",此函數返回"my cat.jpg"
- MultiPartData.isFile(),此函數判斷該MultiPartData對象是不是文件類型的數據,如果是,返回true,否則返回false。
- MultiPartData.toFile(String target),把當前MultiPartData對象中的數據緩沖寫入到指定的文件當中去。寫入成功,返回true,如果該對象中無任何數據,直接返回false
- MultiPartData.getContentBuffer(),返回MultiPartData對象中數據緩沖,如果該MultiPartData不包含任何數據,返回null
-
MultiPartData.getBytes(),返回該MultiPartData對象中數據緩沖的字節數。如果是0,表示當前對象中不包含任何數據