最近搞項目需要實現將前端文件上傳至后台服務器保存起來的功能,很輕松的將之前的代碼復制黏貼一份,本以為就此完成,結果調試時,被坑殘了。
后台上傳文件功能用的是MultipartFile來接收前端的文件,大概方法簡寫如下:
void uploadFile(MultipartFile uploadFile) throws Exception { if(uploadFile!=null && uploadFile.getSize()>0){ String path = "/var/uploadFiles"; // 文件原名 String fileName = uploadFile.getOriginalFilename(); // 文件后綴 String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); // FTP存放名 String realFileName = (new Date()).getTime().concat(".").concat(suffix); File file = new File(path, realFileName); if(file.getParentFile().exists()) { file.getParentFile().mkdirs(); } // 存入臨時文件 uploadFile.transferTo(file); } }
這串上傳代碼看着沒什么問題,唯一的問題就是path用的是相對路徑的寫法,但這種寫法在Windosws中其實也是允許的。然而,就是這種相對目錄的寫法,在配合file.getParentFile().exists()和MultipartFile.transferTo()把我坑慘了,除了第一次運行以外其他每次運行時file.getParentFile().exists()都是返回true,而向下運行uploadFile.transferTo(file);時,卻每次都報找不到文件路徑異常,簡直一臉懵逼,一個getParentFile().exists()說父級目錄存在,一個uploadFile.transferTo(file)又提示異常說目錄不存在,十分詭異,沒法子,只能網上找答案了,找了一會才由這篇博客https://blog.csdn.net/lcczpp/article/details/88887045中找到問題,原因如下:

file.getParentFile().mkdirs()對於相對目錄,默認采用當前程序運行所在盤符(我運行的時候在D:盤),而MultipartFile.transferTo()對於相對目錄,默認采用temp目錄(temp目錄在C:盤)為父目錄,所以,file.getParentFile().mkdirs()根據我提供的相對目錄在D:盤創建了父級目錄,而MultipartFile.transferTo()則將文件傳入到C:盤,但C:盤不存在這個父級目錄所以異常報錯,找到問題了,剩下的解決方案,博客中也說了,使用new File(path).getAbsolutePath()就可以。
so,問題解決,最后總結一下,當使用MultipartFile.transferTo(File)方法時,傳入的File不能直接使用,而應該轉一道MultipartFile.transferTo(File.getAbsoluteFile())再用。下面給出修改后的代碼:
void uploadFile(MultipartFile uploadFile) throws Exception { if(uploadFile!=null && uploadFile.getSize()>0){ String path = "/var/uploadFiles"; // 文件原名 String fileName = uploadFile.getOriginalFilename(); // 文件后綴 String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); // FTP存放名 String realFileName = (new Date()).getTime().concat(".").concat(suffix); File file = new File(path, realFileName); if(file.getParentFile().exists()) { file.getParentFile().mkdirs(); } // 存入臨時文件 修改file為file.getAbsoluteFile() uploadFile.transferTo(file.getAbsoluteFile()); } }
