Java Files.createDirectories()抛出FileAlreadyExistsException,但不抛出目录
他问了一个类似的问题。但是,在我的例子中,在调用Java Files.createDirectories()抛出FileAlreadyExistsException,但不抛出目录,java,exception,io,directory,subdirectory,Java,Exception,Io,Directory,Subdirectory,他问了一个类似的问题。但是,在我的例子中,在调用Files.createDirectories()之前或之后,目录不存在。这发生在OracleJDK10.0.2上 这是我的密码 Set<PosixFilePermission> perms; FileAttribute<?> attr; Path path; File directory; directory = new File("/test/http/localhost_4452/UCF2b/Live"); path
Files.createDirectories()
之前或之后,目录不存在。这发生在OracleJDK10.0.2上
这是我的密码
Set<PosixFilePermission> perms;
FileAttribute<?> attr;
Path path;
File directory;
directory = new File("/test/http/localhost_4452/UCF2b/Live");
path = directory.toPath();
perms = EnumSet.noneOf(PosixFilePermission.class);
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_EXECUTE);
attr = PosixFilePermissions.asFileAttribute(perms);
try
{
if (!directory.exists())
Files.createDirectories(path, attr);
}
catch (IOException e)
{
if (!directory.exists())
{
... collect more information about the state of the directory and its parent path ...
... add this information as a suppressed exception ...
throw e;
}
// else do nothing and assume another thread created the directory
}
当前用户是root用户。以下是收集的有关目录及其父目录的诊断信息。如果目录不存在,则在catch
块中收集此信息
+--------------------------------------+--------+----------+--------------------------+---------+-----------+-------+--------+---------+-------+-------+
| Path | Exists | Length | Modified | Owner | Directory | File | Hidden | Execute | Read | Write |
+--------------------------------------+--------+----------+--------------------------+---------+-----------+-------+--------+---------+-------+-------+
| /test/http/localhost_4452/UCF2b/Live | false | 0.00 B | 1970-01-01T00:00:00Z | (null) | false | false | false | false | false | false |
| /test/http/localhost_4452/UCF2b | true | 4.00 kB | 2018-11-04T20:32:09.769Z | root | true | false | false | true | true | true |
| /test/http/localhost_4452 | true | 4.00 kB | 2018-11-04T20:18:26.849Z | root | true | false | false | true | true | true |
| /test/http | true | 4.00 kB | 2018-11-04T20:11:42.605Z | root | true | false | false | true | true | true |
| /test/ | true | 20.00 kB | 2018-11-04T20:32:09.768Z | root | true | false | false | true | true | true |
| / | true | 4.00 kB | 2018-11-04T20:09:22.061Z | root | true | false | false | true | true | true |
+--------------------------------------+--------+----------+--------------------------+---------+-----------+-------+--------+---------+-------+-------+
如您所见,代码在调用Files.createDirectories()
之前检查目录是否存在,并在调用之后验证目录是否不存在。例外情况很少发生。我不明白什么?如何创建目录?如果我只是重复调用Files.createDirectories()
,它将继续失败
编辑:此代码由多个线程调用。这意味着多个线程可以调用
文件.createDirectories()
,但如果目录最终存在,代码不会重新显示异常。换句话说,其他线程必须在适当的时候创建和删除目录,因为directory.exists()
在Files.createDirectories()之前和之后是false
。此外,这个完美的时机必须持续下去,因为一旦程序遇到这个问题,它在特定目录中不断发生。这段代码很可能被多个线程使用,因为只有这样才能解释为什么在条件为false
时代码会进入if
块,而且这种情况很少发生。一个线程检查目录是否不存在,在创建目录之前,另一个线程会创建它。如果是这种情况,您应该使用同步
synchronized (this) {
if (!directory.exists())
Files.createDirectories(path, attr);
}
我不能经常重复这个问题。我决定用文件.createDirectory()
替换文件.createDirectory()
(即根据需要在路径中创建每个目录)。也许这会奏效。也许这将揭示根本问题
编辑:自从尝试上面的测试和大约1000个单元测试执行以来,已经有一周了。问题没有再发生。我假设上面的答案是有效的。“这段代码很可能被多个线程使用。”-你有什么理由相信吗?你在评论中问过OP吗?@ErwinBolwidt是否有其他可能的解释,如果条件为false
,为什么代码会进入if
块?@ErwinBolwidt用推理更新了答案,谢谢。我编辑了我的问题来讨论并发性。谢谢你的想法。
synchronized (this) {
if (!directory.exists())
Files.createDirectories(path, attr);
}