如何解决Windows上的Java WatchService锁定目录
似乎当您使用Java的WatchService监视目录,然后尝试重命名其父目录时,重命名将失败,并显示AccessDeniedException。该目录似乎已由WatchService锁定。
可以复制:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.*;
public class WatcherTest {
@Test
public void moveWatchedDir(@TempDir Path tempDir) throws Exception {
Files.createDirectories(tempDir.resolve("dir1/dir2"));
var watchService = FileSystems.getDefault().newWatchService();
tempDir.resolve("dir1/dir2").register(watchService,StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_DELETE,StandardWatchEventKinds.ENTRY_MODIFY);
Files.move(tempDir.resolve("dir1"),tempDir.resolve("dir1_b"));
}
}
失败:
java.nio.file.AccessDeniedException: C:\Users\Markus\AppData\Local\Temp\junit14649009910061913524\dir1 -> C:\Users\Markus\AppData\Local\Temp\junit14649009910061913524\dir1_b
at java.base/sun.nio.fs.WindowsException.translatetoIOException(WindowsException.java:89)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsFilecopy.move(WindowsFilecopy.java:395)
at java.base/sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:292)
at java.base/java.nio.file.Files.move(Files.java:1426)
at WatcherTest.moveWatchedDir(WatcherTest.java:13)
在Windows 10上使用OpenJDK 11和14进行了测试。在Windows资源管理器中尝试重命名dir1也会失败。 在Linux上可以正常工作。
还请注意,当观察者未在dir1 / dir2上注册而仅在dir1上注册时,便可以使用。
这是OpenJDK
中的错误吗?查看一些较旧的问题(https://bugs.openjdk.java.net/browse/JDK-8153925),似乎不应发生目录锁定。
解决方法
不,这不是bug。这是Windows的一种设计功能,称为强制锁定。无法禁用它。
Linux使用咨询锁定,这意味着它不会阻止目录的重命名甚至删除。
,@jurez答案是正确的,在Windows上,WatchService将锁定目录。这是known OpenJDK issue,显然无法解决。
但是有一个很好的解决方法。在Windows上,可以监视整个目录结构,而不必像在Linux上那样为每个子目录手动注册监视程序。参见example code。
这应该可以在许多情况下解决此问题。就我而言,我正在开发文件同步工具(datalisk),通过这种解决方法,我只需要监视/锁定顶级目录,这不会对用户造成问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。