递归将目录和文件复制到目的地

发布于 2025-01-23 02:38:19 字数 1399 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

恬淡成诗 2025-01-30 02:38:19

这是一个可以通过 fileVisitor 接口。在这种方法中,可以将代码分为三个部分:

  • 目录访问=创建目标目的地目录的空副本。
  • 文件访问=在先前访问的目录中复制文件。
  • 发布目录访问=打印复制文件夹的总尺寸。
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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文