public class FileCopier implements FileVisitor<Path> {
private final Path sourcePath;
private final Path targetPath;
//Map holding the size of each directory
private final Map<String, Long> mapSize;
public FileCopier(Path sourcePath, Path targetPath) throws IOException {
//Check whether the destination directory exists or not
if (!Files.exists(targetPath)) {
Files.createDirectories(targetPath);
}
this.sourcePath = sourcePath.toRealPath();
this.targetPath = targetPath.toRealPath();
this.mapSize = new HashMap<>();
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
//Copying the directory first, and then its content (copying a directory does not copy its content)
//Retrieving the last bit of the folder's path relatively from the source path ("subtracts" the source path)
Path lastBitPath = sourcePath.relativize(dir.toAbsolutePath().normalize());
//Adding the last bit to the target path
Path targetCopyPath = targetPath.resolve(lastBitPath).toAbsolutePath().normalize();
//Copying the folder is this doesn't exist yet
if (!Files.exists(targetCopyPath)) {
Files.copy(dir, targetCopyPath, StandardCopyOption.COPY_ATTRIBUTES);
}
//Adding a new key-value pair, where the key is the folder's path, while the value is folder's size in bytes
mapSize.put(targetCopyPath.toString(), 0L);
System.out.println("Started: " + targetCopyPath);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//Building the new file path by removing the source path from the file, and then adding the result on top of the target path
Path targetCopyPath = targetPath.resolve(sourcePath.relativize(file.toAbsolutePath().normalize())).toAbsolutePath().normalize();
Files.copy(file, targetCopyPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
//Adding the file's size to the pair's value identified by the folder's path
mapSize.put(targetCopyPath.getParent().toString(), mapSize.get(targetCopyPath.getParent().toString()) + Files.size(file));
System.out.println("Finished FILE: " + targetCopyPath);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.TERMINATE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
//Printing the folder's size after finishing its copy (visit)
//Retrieving the last bit of the folder's path by removing the source location
Path lastBitPath = sourcePath.relativize(dir.toAbsolutePath().normalize());
//Adding the last bit of the folder's path on top of the target path
Path targetCopyPath = targetPath.resolve(lastBitPath).toAbsolutePath().normalize();
//Showing the number of bytes corresponded to the copied directory
System.out.println("Total " + this.mapSize.get(targetCopyPath.toString()) + " bytes were copied into " + targetCopyPath);
return FileVisitResult.CONTINUE;
}
public static void main(String[] args) throws IOException {
Path sourcePath = Paths.get("./test1");
Path targetPath = Paths.get("./test2");
FileCopier fc = new FileCopier(sourcePath, targetPath);
Files.walkFileTree(sourcePath, fc);
}
}
This is a perfect example of a task that can be handled with an implementation of the FileVisitor interface. In this approach, the code can be broken down into three parts:
pre directory visit = create an empty copy of the directory in the target destination.
file visit = copy the file in the directory previously visited.
post directory visit = print the total size of the copied folder.
public class FileCopier implements FileVisitor<Path> {
private final Path sourcePath;
private final Path targetPath;
//Map holding the size of each directory
private final Map<String, Long> mapSize;
public FileCopier(Path sourcePath, Path targetPath) throws IOException {
//Check whether the destination directory exists or not
if (!Files.exists(targetPath)) {
Files.createDirectories(targetPath);
}
this.sourcePath = sourcePath.toRealPath();
this.targetPath = targetPath.toRealPath();
this.mapSize = new HashMap<>();
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
//Copying the directory first, and then its content (copying a directory does not copy its content)
//Retrieving the last bit of the folder's path relatively from the source path ("subtracts" the source path)
Path lastBitPath = sourcePath.relativize(dir.toAbsolutePath().normalize());
//Adding the last bit to the target path
Path targetCopyPath = targetPath.resolve(lastBitPath).toAbsolutePath().normalize();
//Copying the folder is this doesn't exist yet
if (!Files.exists(targetCopyPath)) {
Files.copy(dir, targetCopyPath, StandardCopyOption.COPY_ATTRIBUTES);
}
//Adding a new key-value pair, where the key is the folder's path, while the value is folder's size in bytes
mapSize.put(targetCopyPath.toString(), 0L);
System.out.println("Started: " + targetCopyPath);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//Building the new file path by removing the source path from the file, and then adding the result on top of the target path
Path targetCopyPath = targetPath.resolve(sourcePath.relativize(file.toAbsolutePath().normalize())).toAbsolutePath().normalize();
Files.copy(file, targetCopyPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
//Adding the file's size to the pair's value identified by the folder's path
mapSize.put(targetCopyPath.getParent().toString(), mapSize.get(targetCopyPath.getParent().toString()) + Files.size(file));
System.out.println("Finished FILE: " + targetCopyPath);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.TERMINATE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
//Printing the folder's size after finishing its copy (visit)
//Retrieving the last bit of the folder's path by removing the source location
Path lastBitPath = sourcePath.relativize(dir.toAbsolutePath().normalize());
//Adding the last bit of the folder's path on top of the target path
Path targetCopyPath = targetPath.resolve(lastBitPath).toAbsolutePath().normalize();
//Showing the number of bytes corresponded to the copied directory
System.out.println("Total " + this.mapSize.get(targetCopyPath.toString()) + " bytes were copied into " + targetCopyPath);
return FileVisitResult.CONTINUE;
}
public static void main(String[] args) throws IOException {
Path sourcePath = Paths.get("./test1");
Path targetPath = Paths.get("./test2");
FileCopier fc = new FileCopier(sourcePath, targetPath);
Files.walkFileTree(sourcePath, fc);
}
}
发布评论
评论(1)
这是一个可以通过
fileVisitor
接口。在这种方法中,可以将代码分为三个部分:This is a perfect example of a task that can be handled with an implementation of the
FileVisitor
interface. In this approach, the code can be broken down into three parts: