檔案上傳是 Web 開發高頻需求。早期 SmartUpload 佔據統治地位,後來 Apache Commons FileUpload 以串流處理、低記憶體佔用成為主流選擇。本文從原理、程式碼、效能三維度對比,並給出遷移建議。
SmartUpload.upload() 一鍵完成。SmartUpload.jar 無額外依賴。SmartUpload su = new SmartUpload();
su.initialize(pageContext);
su.setMaxFileSize(500 * 1024 * 1024); // 500MB
su.upload();
for (int i = 0; i < su.getFiles().getCount(); i++) {
com.jspsmart.upload.File file = su.getFiles().getFile(i);
if (!file.isMissing()) {
file.saveAs(savePath + file.getFileName(), su.SAVE_PHYSICAL);
}
}
OutOfMemoryError。DiskFileItem),僅在記憶體保留小檔案 (閾值可配置)。FileItem, FileItemFactory, FileUpload 易於擴充 (如資料庫儲存、雲端儲存)。@MultipartConfig 原生整合。DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(4096); // 4KB 以下存記憶體
factory.setRepository(new File("D:/Tomcat5/TEMP")); // 臨時目錄
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(10_000_000); // 10MB 單檔上限
upload.setSizeMax(50_000_000); // 50MB 總請求上限
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items) {
if (!item.isFormField()) { // 過濾一般表單欄位
String fileName = new File(item.getName()).getName(); // 防路徑遍歷
item.write(new File("D:/UploadTest", fileName));
}
}
| 指標 | SmartUpload | Commons FileUpload |
|---|---|---|
| 記憶體模型 | 全量載入 Heap | 閾值分流:小檔案記憶體、大檔案磁碟 |
| 大檔案支援 | 差 (易 OOM) | 優 (GB 級可上傳) |
| 並發穩定性 | 低 (需重啟容器) | 高 (無狀態、線程安全) |
| API 靈活度 | 單一巨石類 | 介面導向、可替換儲存策略 |
| 維護狀態 | 停止維護 (2005 年後無更新) | 活躍維護 (最新 1.5 版 2023 年釋出) |
| 依賴 | 無 | commons-io |
new File(item.getName()).getName() 防止目錄遍歷。Apache Tika 或 magic numbers 檢測真實檔案類型。Resumable.js + 自定義 FileItemFactory。request.getParts() 標準 API,零依賴,但缺乏進階流控 (大小限制、臨時目錄) 需在 @MultipartConfig 或 web.xml 配置。「HTTP 方式傳檔案效率始終很低,我們現在使用 Web 方式實現的 FTP 檔案上傳。」
對於 GB 級、跨國、弱網環境大檔案傳輸,HTTP/1.1 缺乏並行、斷點續傳、壓傳輸層優化。現代方案: