How to Copy Non Empty Directory with Files in Java 7 - Example Tutorial

It's easy to copy a file or empty directory in Java as you can use Files.copy(fromPath, toPath) from Java 7, but, unfortunately, it's not as easy to copy a non-empty directory with all its files and subdirectories in Java, much like deleting a non-empty directory. There is no method in Java IO API which copies everything inside one directory to another. The copy(source, target, CopyOption...) method can copy directories, but files inside the directories are not copied. So the new directory will be empty even if the original directory contains files and folders. Similarly, the copy fails if target directory already exists, unless the REPLACE_EXISTING copy option is specified. No doubt that NIO 2 of Java 7 has made life easier for Java programmers and provides useful tools to deal with files and directories, the onus is now on Java developers to learn and make the best use of it. If you to learn more about NIO 2 features, see here.

In this article, I'll show you two ways to copy a directory with files in Java. The first option is by using FileUtils class from Apache Commons IO. You can use FileUtils.copyDirectory(src, target) method to copy or backup directories in Java.



The second example will copy directory structure in using NIO2 of Java 7. It use will use a recursive algorithm to copy the directory in Java. To learn more about JDK 7 new File API and other features, you can see Core Java For the Impatient. This contains many, easy to understand examples to quickly learn new features of Java 7 including the new file API and it also covers Java SE 8.

How to copy Directory with Files in Java





Copy Directory using Apache Commons IO FileUtils class

This was the simplest way to recursively copy a directory with full file structure prior to Java 7 world. It is still very useful to many Java developers like me who always use Apache Commons library in their Java projects. In order to use Apache Commons IO, you need to include following Maven dependency:

<dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.4</version>
</dependency>

and here is the sample Java function which copies a directory with files in just one line. That's the benefit of library methods, it makes your code more readable. No doubt, why Joshua Bloch has recommended to learn and use library methods in his classic Effective Java.

public static void copyDirectoryUsingApache(String from, String to) throws IOException{
        File source = new File(from);
        File target = new File(to);
     
        FileUtils.copyDirectory(source, target);     
}

You can see that how easy to copy a full directory in Java with just one line of code. Yes, you can remove first two lines of code which are converting String to File object, if you directly pass File object. Though if you have file names as String, it's better to use the method in this format.



Java Program to Copy a Non-Empty Directory

In order to copy a file or a directory in JDK 1.7,  simply calling Files.copy(fromPath, toPath) is enough, but it will only work if source directory is not empty. In order to copy a directory with files and subdirectories, you need to write your own Java program to copy whole directory structure in Java as shown below. This method uses recursion to copy all files and folder from the directory.

public static void copyDirectory(File sourceDir, File targetDir)
 throws IOException {
        if (sourceDir.isDirectory()) {
            copyDirectoryRecursively(sourceDir, targetDir);
        } else {
            Files.copy(sourceDir.toPath(), targetDir.toPath());
        }
    }
// recursive method to copy directory and sub-diretory in Java
private static void copyDirectoryRecursively(File source, File target)
 throws IOException {
        if (!target.exists()) {
            target.mkdir();
        }

        for (String child : source.list()) {
            copyDirectory(new File(source, child), new File(target, child));
        }
    }

The method copyDirectory(File src, File dest) first checks if src File object points to a directory or not if it does then it call the recursive method to copy the directory, but if it doesn't then it just copy the file using Files.copy() method. It also creates the target directory if it doesn't exists. If the directory already exists and you use REPLACE_EXISTING option then it will overwrite it.

There are a couple of more copy options which are useful e.g. COPY_ATTRIBUTE, which copies the file attribute e.g. permissions to the target file while copying. The exact file attributes supported are file system and platform dependent, but last-modified-time is supported across the platform and copied to the target file.

Another thing to note is whether to copy the soft links or not. It's possible that your directory may contain symbolic links. The copy method copies the target of the link, instead of the link itself. So if you want to copy the link itself, and not the target of the link, specify either the NOFOLLOW_LINKS or REPLACE_EXISTING option

Here is how our newly copied directory looks like, when I used this method to copy an existing directory in my laptop.





That's all about how to copy nonempty directory in Java with files and folders. If you are not running in Java 7, though you should because it has lots of performance improvement, you can use Apache Commons IO to copy the directories with files and folder in Java. If you are running on JRE 7 then you can write your own recursive method using Files.copy() method and various CopyOption e.g. RELACE_EXISTING, COPY_ATTRIBUTE, and NOFOLLOW_LINKS.

No comments :

Post a Comment