在服务器中,我在首次访问资源时初始化资源的工作目录。服务器的多个进程处理的资源可能存在并行请求,这意味着我需要注意没有一个进程看到部分初始化的工作目录。解决方案是在一个临时的同级目录中初始化工作目录,然后Files.move
使用StandardCopyOption.ATOMIC_MOVE
.
如果两个进程同时初始化一个工作目录,则第二个原子移动失败。这不是一个真正的问题,因为工作目录已正确初始化,因此第二个进程只需要丢弃它创建的临时目录并继续。
我尝试使用以下代码执行此操作:
private void initalizeWorkDirectory(final Resource resource) throws IOException {
File workDir = resource.getWorkDirectory();
if (!workDir.exists()) {
File tempDir = createTemporarySibligDirectory(workDir);
try {
fillWorkDirectory(tempDir, resource);
Files.move(tempDir.toPath(), workDir.toPath(), StandardCopyOption.ATOMIC_MOVE);
} catch (FileAlreadyExistsException e) {
// do some logging
} finally {
FileUtils.deleteQuietly(tempDir);
}
}
}
但是我注意到,仅仅捕捉FileAlreadyExistsException
似乎是不够的。如果发生移动碰撞,还会引发其他异常。我不只是想捕获所有异常,因为这可能隐藏真正的问题。
那么有没有办法从 Files.move 抛出的异常中可靠地检测到由于目标目录已经存在而导致目录的原子移动失败?