问题
有一段代码逻辑,是
// 文件路径
String folderPath = filePath + File.separator + "excelTemp";
// 如果不存在文件夹,则创建
File folderFile = new File(folderPath);
if (!folderFile.exists()) {
folderFile.mkdirs();
}
String tempFilePath = filePath + File.separator + "excelTemp" + File.separator + receiveIdStr + DateUtil.format(new Date(), DateUtil.PATTERN_DATETIME_MINI) + ".xlsx";
File file = new File(tempFilePath);
try {
// 写入文件
ExcelWriter excelWriter = EasyExcel.write(Files.newOutputStream(file.toPath())).build();
…………
} catch (IOException e) {
log.error("下载清关模板异常", e);
throw new ShipException("下载清关模板失败");
}
这段代码在本地和测试环境调试都没有问题,但是上到生产后直接报错了,在写入文件时报了文件不存在
分析
排查后发现,是mkdirs方法创建文件夹失败了,创建失败时不会有异常抛出,只是会返回false。
咦?原来还会失败吗,让我们重点关注一下mkdirs方法:
/**
* 创建由此抽象路径名命名的目录,包括任何必要但不存在的父目录。请注意,如果此操作失败,则可能已成 功创建一些必要的父目录。
*
* @return <code>true</code> if and only if the directory was created,
* along with all necessary parent directories; <code>false</code>
* otherwise
*
* @throws SecurityException
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method does not permit verification of the existence of the
* named directory and all necessary parent directories; or if
* the <code>{@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
* method does not permit the named directory and all necessary
* parent directories to be created
*/
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {
return true;
}
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
File parent = canonFile.getParentFile();
return (parent != null && (parent.mkdirs() || parent.exists()) &&
canonFile.mkdir());
}
方法返回是否创建成功:
- true- 创建成功
- false-创建失败
当以下情况时,是有可能创建失败的:
- 权限不足
- 路径无效
- 文件系统限制
- 目录已存在
解决
我遇到的情况就是权限不足,程序的启动用户并没有该文件夹的写权限,需要注意的是mkdirs
方法不会抛异常,所以对方法的返回值的处理就很重要,我对代码进行了如下修改:
// 文件路径
String folderPath = filePath + File.separator + "excelTemp";
File folderFile = new File(folderPath);
if (!folderFile.exists()) {
// 当创建失败时抛异常
if(!folderFile.mkdirs()){
throw new RuntimeException("无法创建目录!" +folderPath);
}
}
当创建文件夹失败时,抛出异常,给到前端提示。