Sunday, May 7, 2023

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

It's easy to copy a file or an 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 the 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.

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.

Btw, I am expecting that you are familiar with basic Java Programing and Java API in general. If you are a complete beginner then I suggest you first go through these Java Programming and development courses to learn more about core Java basics as well as such gems from Java API.

The second example will copy the directory structure using NIO2 of Java 7. Its use will use a recursive algorithm to copy the directory in Java.







How to copy directory using Apache Commons IO FileUtils class? Example

This was the simplest way to recursively copy a directory with a full file structure prior to Java 7 world. It is still very useful to many Java developers like me who always use the Apache Commons library in their Java projects. In order to use Apache Commons IO, you need to include the 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 learning 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 how easy to copy a full directory in Java with just one line of code. Yes, you can remove the first two lines of code which are converting String to the File object, if you directly pass File object. Though if you have filenames as String, it's better to use the method in this format.

How to Copy Non Empty Directory with Files in Java




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 the 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 the whole directory structure in Java as shown below. 

This method uses recursion to copy all files and folders 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 the src File object points to a directory or not if it does then it calls 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 exist. If the directory already exists and you use REPLACE_EXISTING option then it will overwrite it.

There are a couple of more copy options that are useful like COPY_ATTRIBUTE, which copies the file attribute like 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 on my laptop.


how to copy directories in Java


That's all about how to copy the 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 folders in Java. 

If you are running on JRE 7 then you can write your own recursive method using Files.copy() method and various CopyOption like RELACE_EXISTING, COPY_ATTRIBUTE, and NOFOLLOW_LINKS.

P. S. -  To learn more about JDK 7 new File API and other features, you can also see these free Java courses. 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.

No comments :

Post a Comment