今天遇到一个问题,测试环境调Files.createTempFile创建成功,MultipartFile转写入却报FileNotFoundException文件找不着了。
觉得很奇怪,后来发现是因为启动参数设置临时文件目录导致的,那为什么创建时可以,后面又找不着呢?这就要理解程序运行时工作目录在哪里。我的复现Demo代码如下。
@PostMapping("/upload")
public Boolean upload(MultipartFile file) throws Exception{
File tempFile = Files.createTempFile("test","txt").toFile();
file.transferTo(tempFile);
System.out.println(tempFile.getAbsolutePath());
return true;
}
当我启动脚本设置java临时工作目录时
-Djava.io.tmpdir=./tmp指定了程序的临时文件目录在相对于程序启动目录下的tmp文件夹。springboot内置的tomcat会在此文件夹下创建它的临时工作目录。用于接收multipartfile等文件。
可以看到它创建了tomcat.8888.一大串数字的文件夹。
Files.createTempFile方法创建临时文件则放在tmp目录下。而当程序file.transferTo(tempFile);执行时。工作目录变成了图中work/tomcat/localhost/root,它去这下边找tmp文件夹下的临时文件,就找不到了。
java.io.FileNotFoundException: /Users/chovy/IdeaProjects/my-test/tmp/tomcat.8888.11804508792040728329/work/Tomcat/localhost/ROOT/./tmp/test317919446680729755txt (No such file or directory)
那设置server.tomcat.basedir有没用呢,Spring配置文件配置了这个为./tmp 启动时,告诉tomcat运行时根文件夹。少了一层tomcat.8888.*** 文件夹而已。问题没有解决。
好了。知道了原因就很好解决 。临时文件夹目录改为绝对路径就好了。我是用shell脚本启动程序的。
可以改为动态获取项目工作目录,然后该绝对路径设置为临时目录的父级别
CURRENT_DIR = $(pwd)
-Djava.io.tmpdir=$CURRENT_DIR/tmp
问题解决,记录一下。