Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Recursively copy directories and files into destination

We have the following task in Java:

Given a list of directories and files followed by the destination copy all these directories(recursively) and files into the destination. Note: all the subdirectories and files inside the given directories must be kept in the same nested structure in destination folder.

We take array of files as an input as well as the destination folder. The output must produce something like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Started: resources\docs\books...
Started: resources\docs\books\american...
Started: resources\docs\books\american\London...
Started: resources\docs\books\american\London\BEFORE ADAM.txt...
Finished FILE: resources\docs\books\american\London\BEFORE ADAM.txt
Total 229KB were copied!
Started: resources\docs\books\american\London\THE IRON HEEL.txt...
Finished FILE: resources\docs\books\american\London\THE IRON HEEL.txt
Total 528KB were copied!
Started: resources\docs\books\american\London\The People of the Abyss.txt...
Finished FILE: resources\docs\books\american\London\The People of the Abyss.txt
Total 370KB were copied!
Finished FOLDER: resources\docs\books\american\London
Finished FOLDER: resources\docs\books\american

Does anyone have any ideas?

>Solution :

You could easily achieve this by implementing the FileVisitor interface. This is a code sample just to show you how it works. It should do what you asked.

public class FileCopier implements FileVisitor<Path> {

    private final Path sourcePath;
    private final Path targetPath;

    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();
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        //Copying the directory first and then its content (directory copy does not copy its content)

        //Retrieving the last bit of the path starting from the source location
        Path lastBitPath = sourcePath.relativize(dir.toAbsolutePath().normalize());

        //Adding the last bit to the target path
        Path targetCopyPath = targetPath.resolve(lastBitPath).toAbsolutePath().normalize();

        if (!Files.exists(targetCopyPath)){
            Files.copy(dir, targetCopyPath, StandardCopyOption.COPY_ATTRIBUTES);
        }

        System.out.println("Started: " + targetCopyPath);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Path targetCopyPath = targetPath.resolve(sourcePath.relativize(file.toAbsolutePath().normalize())).toAbsolutePath().normalize();
        Files.copy(file, targetCopyPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
        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 {
        //This is a placeholder, Files.size() works for files not directory. I've written it like this for simplicity, if you need the size you should account for it at every file visit and reset the value at every preFolder visit.
        System.out.println("Total " + Files.size(dir) + " were copied!");
        return FileVisitResult.CONTINUE;
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading