[英]Java move sub directory with files and structure to parent directory
嘗試將文件從子目錄以及結構移動到父目錄。 並且無法使用Files.move()
完成此Files.move()
。 為了說明問題,請參見下面的目錄結構。
$ tree
.
└── b
├── c
│ ├── cfile.gtxgt
│ └── d
│ ├── dfile.txt
│ └── e
└── x
└── y
└── z
├── 2.txt
└── p
├── file1.txt
└── q
├── file
├── file2.txt
└── r
└── 123.txt
我想通過Java模擬以下move命令。
$ mv b/x/y/z/* b/c
b/x/y/z/2.txt -> b/c/2.txt
b/x/y/z/p -> b/c/p
輸出應該類似於
$ tree
.
└── b
├── c
│ ├── 2.txt
│ ├── cfile.gtxgt
│ ├── d
│ │ ├── dfile.txt
│ │ └── e
│ └── p
│ ├── file1.txt
│ └── q
│ ├── file
│ ├── file2.txt
│ └── r
│ └── 123.txt
└── x
└── y
└── z
在此移動中,目錄z
下的所有文件和目錄都已移動到c
。
我試圖做到這一點:
public static void main(String[] args) throws IOException{
String aPath = "/tmp/test/a/";
String relativePathTomove = "b/x/y/z/";
String relativePathToMoveTo = "b/c";
Files.move(Paths.get(aPath, relativePathTomove), Paths.get(aPath, relativePathToMoveTo), StandardCopyOption.REPLACE_EXISTING);
}
但是,這會導致拋出的java.nio.file.DirectoryNotEmptyException: /tmp/test/a/b/c
出現此異常,並且如果取出REPLACE_EXISTING
選項,則代碼將拋出java.nio.file.FileAlreadyExistsException: /tmp/test/a/b/c
。
該問題的答案使用遞歸函數來解決此問題。 但就我而言,這將涉及進一步的復雜性,因為我什至需要在新位置重新創建子目錄結構。
我沒有嘗試使用commons-io
實用程序方法org.apache.commons.io.FileUtils#moveDirectoryToDirectory
的選項,因為此代碼似乎是先復制文件,然后再從原始位置刪除它們。 就我而言,文件很大,因此這不是首選。
如何在不訴諸復制的情況下實現Java中的move功能。 單個文件移動是我唯一的選擇嗎?
TLDR:如何在Java中模擬mv
功能,以將帶有文件和結構的子目錄移動到父目錄。
我最終這樣做:
創建一個FileVisitor
實現,如下所示:
package com.test.files;
import org.apache.log4j.Logger;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;
import static java.nio.file.FileVisitResult.TERMINATE;
public class MoveFileVisitor implements FileVisitor<Path> {
private static final Logger LOGGER = Logger.getLogger(MoveFileVisitor.class);
private final Path target;
private final Path source;
public MoveFileVisitor(@NotNull Path source, @NotNull Path target) {
this.target = Objects.requireNonNull(target);
this.source = Objects.requireNonNull(source);
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path relativePath = source.relativize(dir);
Path finalPath = target.resolve(relativePath);
Files.createDirectories(finalPath);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path relativePath = source.relativize(file);
Path finalLocation = target.resolve(relativePath);
Files.move(file, finalLocation);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
LOGGER.error("Failed to visit file during move" + file.toAbsolutePath(), exc);
return TERMINATE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
}
然后像這樣與這位訪問者一起走這條路:
String source = "/temp/test/a/b/x/y/z";
String target = "/temp/test/a/b/c";
MoveFileVisitor visitor = new MoveFileVisitor(Paths.get(source), Paths.get(target));
Files.walkFileTree(Paths.get(source), visitor);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.