1. Introduction

In this short tutorial, we’ll see how to copy a directory in Java, including all its files and subdirectories. This can be achieved by using core Java features or third-party libraries.

2. Using the java.nio API

Java NIO has been available since Java 1.4. Java 7 introduced NIO 2 that brought a lot of useful features like better support for handling symbolic links, file attributes access. It also provided us with classes such as Path, Paths, and Files that made file system manipulation much easier.

Let’s demonstrate this approach:

public static void copyDirectory(String sourceDirectoryLocation, String destinationDirectoryLocation) 
  throws IOException {
    Files.walk(Paths.get(sourceDirectoryLocation))
      .forEach(source -> {
          Path destination = Paths.get(destinationDirectoryLocation, source.toString()
            .substring(sourceDirectoryLocation.length()));
          try {
              Files.copy(source, destination);
          } catch (IOException e) {
              e.printStackTrace();
          }
      });
}

In this example, we walked the file tree rooted at the given source directory using Files.walk() and invoked Files.copy() for each file or directory we found in the source directory.

3. Using the java.io API

Java 7 was a turning point from the file system management perspective since it introduced a lot of new handy features.

However, if we want to stay compatible with older Java versions, we can copy a directory using recursion and java.io.File features:

private static void copyDirectory(File sourceDirectory, File destinationDirectory) throws IOException {
    if (!destinationDirectory.exists()) {
        destinationDirectory.mkdir();
    }
    for (String f : sourceDirectory.list()) {
        copyDirectoryCompatibityMode(new File(sourceDirectory, f), new File(destinationDirectory, f));
    }
}

In this case, we’ll create a directory in the destination directory for every directory in the source directory tree. Then we’ll invoke the copyDirectoryCompatibityMode() method:

public static void copyDirectoryCompatibityMode(File source, File destination) throws IOException {
    if (source.isDirectory()) {
        copyDirectory(source, destination);
    } else {
        copyFile(source, destination);
    }
}

Also, let’s see how to copy a file using FileInputStream and FileOutputStream:

private static void copyFile(File sourceFile, File destinationFile) 
  throws IOException {
    try (InputStream in = new FileInputStream(sourceFile); 
      OutputStream out = new FileOutputStream(destinationFile)) {
        byte[] buf = new byte[1024];
        int length;
        while ((length = in.read(buf)) > 0) {
            out.write(buf, 0, length);
        }
    }
}

4. Using Apache Commons IO

Apache Commons IO has a lot of useful features like utility classes, file filters, and file comparators**.** Here we’ll be using FileUtils that provide methods for easy file and directory manipulation, i.e., reading, moving, copying.

Let’s add commons-io to our pom.xml file:

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

Finally, let’s copy a directory using this approach:

public static void copyDirectory(String sourceDirectoryLocation, String destinationDirectoryLocation) throws IOException {
    File sourceDirectory = new File(sourceDirectoryLocation);
    File destinationDirectory = new File(destinationDirectoryLocation);
    FileUtils.copyDirectory(sourceDirectory, destinationDirectory);
}

As shown in the previous example, Apache Commons IO makes it all much easier, since we only need to call FileUtils.copyDirectory() method.

5. Conclusion

This article illustrated how to copy a directory in Java. Complete code samples are available over on GitHub.