最近搞项目需要实现将前端文件上传至后台服务器保存起来的功能,很轻松的将之前的代码复制黏贴一份,本以为就此完成,结果调试时,被坑残了。
后台上传文件功能用的是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()); } }