在java中移动目录会引发java.nio.file.FileAlreadyExistsException
我正在创建一个回滚功能,以下是我所拥有和想要实现的:在java中移动目录会引发java.nio.file.FileAlreadyExistsException,java,windows,Java,Windows,我正在创建一个回滚功能,以下是我所拥有和想要实现的: 在与数据文件夹相同的位置创建tmp文件夹 在执行任何操作之前,我将所有内容从数据文件夹复制到tmp文件夹(少量数据) 回滚时,我想删除数据文件夹,并将tmp文件夹重命名为数据文件夹 这就是我试过的 String contentPath = "c:\\temp\\data"; String tmpContentPath = "c:\\temp\\data.TMP"; if (Files.exists(Paths.get(tmpC
数据文件夹相同的位置创建tmp文件夹
数据文件夹
复制到tmp文件夹
(少量数据)数据文件夹
,并将tmp文件夹
重命名为数据文件夹
String contentPath = "c:\\temp\\data";
String tmpContentPath = "c:\\temp\\data.TMP";
if (Files.exists(Paths.get(tmpContentPath)) && Files.list(Paths.get(tmpContentPath)).count() > 0) {
FileUtils.deleteDirectory(new File(contentPath));
Files.move(Paths.get(tmpContentPath), Paths.get(contentPath), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
}
但这会引发filealreadyexistException
,即使我用相同的方法删除了目标目录
一旦程序退出,我就看不到c:\temp\data
目录,因此该目录实际上已被删除
现在,如果我尝试StandardCopyOption.ATOMIC\u移动,它会抛出一个java.nio.file.AccessDeniedException
在这种情况下,将
tmp dir
移动到data dir
的最佳方法是什么?实际上,在java 7或更高版本中,即使存在冲突,您也可以使用来实现文件夹移动,这意味着目标文件夹已经存在
private static void moveFolder(Path thePath, Path targetPath) {
if (Files.exists(targetPath)) { // if the target folder exists, delete it first;
deleteFolder(targetPath);
}
try {
Files.move(thePath, targetPath);
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void deleteFolder(Path path) {
try {
if (Files.isRegularFile(path)) { // delete regular file directly;
Files.delete(path);
return;
}
try (Stream<Path> paths = Files.walk(path)) {
paths.filter(p -> p.compareTo(path) != 0).forEach(p -> deleteFolder(p)); // delete all the children folders or files;
Files.delete(path); // delete the folder itself;
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void moveFolder(路径thePath,路径targetPath){
如果(Files.exists(targetPath)){//如果目标文件夹存在,请先将其删除;
删除文件夹(targetPath);
}
试一试{
移动(路径、目标路径);
}捕获(忽略IOException){
已忽略。printStackTrace();
}
}
专用静态void deleteFolder(路径){
试一试{
if(Files.isRegularFile(path)){//直接删除常规文件;
删除(路径);
返回;
}
尝试(流路径=文件。行走(路径)){
paths.filter(p->p.compareTo(path)!=0).forEach(p->deleteFolder(p));//删除所有子文件夹或文件;
Files.delete(path);//删除文件夹本身;
}
}捕获(忽略IOException){
已忽略。printStackTrace();
}
}
解决了这个问题。在执行回滚之前的代码中,我正在执行备份,在该方法中,我使用本节进行复制
if (Files.exists(Paths.get(contentPath)) && Files.list(Paths.get(contentPath)).count() > 0) {
copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));
}
改成
try (Stream<Path> fileList = Files.list(Paths.get(contentPath))) {
if (Files.exists(Paths.get(contentPath)) && fileList.count() > 0) {
copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));
}
}
try(streamfilelist=Files.list(path.get(contentPath))){
if(Files.exists(path.get(contentPath))&&fileList.count()>0){
copyPath(path.get(contentPath)、path.get(tmpContentPath));
}
}
要解决此问题,感谢您的回复。如果你看我的代码,我已经在使用文件了。move@gechu我为你编辑了你的问题。我检查了你的代码。在您的代码中,已存在的目录阻止了您的移动,因此在我的解决方案中,我使用纯java代码删除了它。那么我可以问一下你在这里担心什么吗?谢谢你的回复。我在我的系统上测试了你的代码。这对我仍然不起作用。我仍然得到java.nio.file.FileAlreadyExistsException。事实上,我还尝试使用Files.walkFileTree方法删除文件夹,但也没有成功。
try (Stream<Path> fileList = Files.list(Paths.get(contentPath))) {
if (Files.exists(Paths.get(contentPath)) && fileList.count() > 0) {
copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));
}
}