我正在创建回滚功能,这是我想要实现的功能:
在与tmp folder
相同的位置创建一个data folder
;
在执行任何操作之前,我将所有内容从data folder
复制到tmp folder
(少量数据)。
在回滚时,我想删除data folder
并将重命名 tmp folder
更改为data folder
。
这是我尝试过的
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);
}
但是即使我以相同的方法删除了目标目录,也会抛出FileAlreadyExistsException
。
程序退出后,我将看不到c:\temp\data
目录,因此该目录实际上已被删除。
现在,如果我尝试使用StandardCopyOption.ATOMIC_MOVE,它将引发java.nio.file.AccessDeniedException。
在这种情况下将tmp dir
移至data dir
的最佳方法是什么?
答案 0 :(得分:0)
实际上,在Java 7或更高版本中,即使存在冲突,也可以使用Files来实现文件夹的移动,这意味着目标文件夹已经存在。
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();
}
}
答案 1 :(得分:0)
Try This
public class MoveFolder
{
public static void main(String[] args) throws IOException
{
File sourceFolder = new File("c:\\temp\\data.TMP");
File destinationFolder = new File("c:\\temp\\data");
if (destinationFolder.exists())
{
destinationFolder.delete();
}
copyAllData(sourceFolder, destinationFolder);
}
private static void copyAllData(File sourceFolder, File destinationFolder)
throws IOException
{
destinationFolder.mkdir();
String files[] = sourceFolder.list();
for (String file : files)
{
File srcFile = new File(sourceFolder, file);
File destFile = new File(destinationFolder, file);
copyAllData(srcFile, destFile); //call recursive
}
}
}
答案 2 :(得分:0)
找出问题所在。在执行回滚之前的代码中,我正在执行备份,在该方法中,我正在使用本节进行复制
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));
}
}
解决问题