Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Files.createDirectories()抛出FileAlreadyExistsException,但不抛出目录_Java_Exception_Io_Directory_Subdirectory - Fatal编程技术网

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);
}