Monday, September 2, 2024

How to recursive copy directory in Java with sub-directories and files? Example

Hello guys, it's a common requirement in Java to copy a whole directory with sub-directories and files but it's not that straightforward, 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 the 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 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


If you want to learn more about the File and Directory class in Java, check out a Java fundamental course like Java Fundamentals: The Java Language on Pluralsight. If you don't know, Pluralsight has made all their courses free for one month as part of their Free April offer. If you want to learn, this is a good chance to join Pluralsight for free.

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



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, it's 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 files from one folder to another in Java.


Other Java File and directory tutorials you may like
  • How to delete a directory with files in Java? (example)
  • How to copy a non-empty directory in Java? (example)
  • How to create a file and directory in Java? (solution)
  • How to read a ZIP archive in Java? (solution)
  • 2 ways to read a text file in Java? (example)
  • How to append text to an existing file in Java (solution)
  • How to write to file using BufferedWriter in Java? (example)
Thanks for reading this article so far. If you like this article then please share it with your friends and colleagues. If you have any questions or suggestions then please drop a comment.

P. S. - If you are looking for free courses to learn all the new and important Java features introduced between Java 8 and Java 13 then you can also see this list of online Java courses on Medium. It includes short and focused courses to learn new JDK features from JDK 8 to JDK 13.

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.