Sunday, April 19, 2020

How to recursive copy directory in Java with sub-directories and file

Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Prep

Hello guys, it's a common requirement in Java to copy a whole directory with sub-directories and files but it's not that straight forward, especially not until Java 7. JDK 7 introduced some new file utility methods as part of Java NIO 2 which we will use in this article to show you how to recursively copy a whole directory with sub-directories and files in Java. I'll also show you how you can use Apache Commons if you are not running on Java 7 or higher versions. Basically, You can copy a file or directory by using the copy(Path, Path, CopyOption...) method. The copy fails if the target file exists unless the REPLACE_EXISTING option is specified.

This method can be used to copy directories but, files inside the directory are not copied, so the new directory is empty even when the original directory contains files. This is the key thing to remember because many developers just call this method and think they are done with it. They don't bother to check if the directory is empty or not.

In order to copy the whole directory with all its sub-directories and files, you need to recursively copy each item unless you reach the top of the directory. When copying a symbolic link, the target of the link is copied. If you want to copy the link itself, and not the contents of the link, specify either the NOFOLLOW_LINKS or REPLACE_EXISTING option.

The following Java code shows how to use the copy method:

import static java.nio.file.StandardCopyOption.*;
...
Files.copy(source, target, REPLACE_EXISTING);

Later, I will show you a complete example of copying whole directory recursively with all their content but if you want to learn more about Java NIO and Files utility class I suggest you go through a comprehensive Java course like The Complete Java Masterclass on Udemy. It's also one of the most up-to-date courses to learn Java and covers new features from recent Java releases.

The copyDirectory Example From Apache Commons

If you are thinking that above method is too complex to use this method then you can also try using the copyDirectory(File srcDir, File destDir) method from the Apache Commons IO library instead.

You can use this method from Apache Commons when you are copying a whole directory to a new location and preserving the file dates. This method copies the specified directory and all its child directories and files to the specified destination. The destination is the new location and name of the directory.

The destination directory is created if it does not exist. If the destination directory did exist, then this method merges the source with the destination, with the source taking precedence.

Note: This method tries to preserve the files' last modified date/times using File.setLastModified(long), however, it is not guaranteed that those operations will succeed.

If the modification operation fails, no indication is provided.

Parameters:
srcDir - an existing directory to copy, must not be null
destDir - the new directory, must not be null

Oracle Java Tutorial and Material, Oracle Java Guides, Oracle Java Learning, Oracle Java Prep

Java Program to Copy a Director with Files and subdirectories


Here is the complete Java program to recursive copy directory in Java with sub-directories and files in Java:

import java.io.File;

import java.io.IOException;

import java.nio.file.FileAlreadyExistsException;

import java.nio.file.FileVisitResult;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.SimpleFileVisitor;

import java.nio.file.attribute.*;

import static java.nio.file.FileVisitResult.*;

import org.apache.commons.io.FileUtils;

/**

   * Java Program to recursive copy directory with sub-directories and files.

   *

   * @author Javin Paul

   */

public class Testing {

    public static void main(String args[]) {

        //copyDir("source", "target");

        copyDirectory("source", "destination");


    }


    /**

     * Java Method to recursive copy directory in Java, including all files and

     * sub-directories. This method, doesn't copy the root directory. For

     * example, it will copy all contents of source directory, but not the

     * source directory itself. which means instead of target directory

     * containing target/source/... it will contain target/...

     *

     * @param source

     * @param destination

     */

    public static void copyDir(String source, String destination) {

        try {

            File srcDir = new File(source);

            File destDir = new File(destination);

            FileUtils.copyDirectory(srcDir, destDir);

            System.out.printf("Method 1 : Directory %s copied 
 successfully to location %s %n", srcDir.getAbsolutePath(), destDir.getAbsolutePath());

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    public static void copyDirectory(String source, String destination) {

        try {

            Files.walkFileTree(Paths.get("source"), 
           new RecursiveFileVisitor(source, destination));

            System.out.printf("Method 2 : Directory %s copied 
            successfully to location %s %n", source, destination);

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    private static class RecursiveFileVisitor extends SimpleFileVisitor {

        private final Path source;

        private final Path target;

        private RecursiveFileVisitor(String source, String target) {

            this.source = Paths.get(source);

            this.target = Paths.get(target);

        }

        @Override

        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {

            Path newdir = target.resolve(source.relativize(dir));

            try {

                Files.copy(dir, newdir);

            } catch (FileAlreadyExistsException x) {

                // ignore

            } catch (IOException x) {

                System.out.format("Failed to create: %s: %s%n", newdir, x);

                return SKIP_SUBTREE;

            }

            return CONTINUE;

        }

        @Override

        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {

            try {

                Files.copy(file, target.resolve(source.relativize(file)));

            } catch (IOException x) {

                System.out.format("Failed to copy: %s: %s%n", source, x);

            }

            return CONTINUE;

        }

        @Override

        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {

            if (exc == null) {

                Path newdir = target.resolve(source.relativize(dir));

                try {

                    FileTime time = Files.getLastModifiedTime(dir);

                    Files.setLastModifiedTime(newdir, time);

                } catch (IOException x) {

                    System.out.format("Failed to copy all attributes to: %s: %s%n",
                               newdir, x);

                }

            }

            return CONTINUE;

        }

        @Override

        public FileVisitResult visitFileFailed(Path file, IOException exc) {

            System.err.format("Failed to copy: %s: %s%n", file, exc);

            return CONTINUE;

        }

    }

}

Output

Method 1 : Directory D:\Eclipse_workspace\Test\source copied successfully 
to location D:\Eclipse_workspace\Test\target

Method 2 : Directory source copied successfully to location destination

Failed to copy: source: java.nio.file.FileAlreadyExistsException: 
destination\config.properties

Failed to copy: source: java.nio.file.FileAlreadyExistsException: 
destination\java\code\Hello.java

Failed to copy: source: java.nio.file.FileAlreadyExistsException: 
destination\test\HelloTest.java

That's all about how to copy recursively copy a directory in Java with sub-directories and files. If you are on Java 7, use Files.copy() the method, its simple and easy and you don't need to include any third party library, but if you are running on Java 6, then you can either use Apache commons IO library and FileUtils.copy() method or you can write your own routing using FileChannel to copy file from one folder to another in Java.

Related Posts

0 comments:

Post a Comment