This article provides an example of how to implement recursion algorithm to copy a whole directory (including its nested child directories and files) to a new location in the file system. Here’s the algorithm we would like to suggest:

    1. List content of the current directory.
    2. For each item in the current directory:
      • If the item is a directory:
        • Create the directory in the new location.
        • Copy this directory by repeating the steps 1, 2, and 3 (At this point the function will call itself, hence the recursion).
      • If the item is a file, copy the file to the new location.

3. Return if the current directory is empty or if the last item is traversed.

We will implement the copy algorithm above in a utility class for the sake of reusability. Here’s structure of the utility class:

public class CopyUtil {

	// utility method which is exposed to the outside
	public static void copyDirectory(File sourceDir, File destDir)
			throws IOException {
		// checks arguments...
		// call copyDirectoryImpl()
	}

	// implementation of copy directory method
	private static void copyDirectoryImpl(File sourceDir, File destDir)
			throws IOException {
		// implements the recursion algorithm above...
		// calls copySingleFile() method
	}

	// copy a file
	private static void copySingleFile(File sourceFile, File destFile)
			throws IOException {
		// code to copy a file to another location
	}
}

Code of the copyDirectory() method:

/**
 * Copy a whole directory to another location.
 * @param sourceDir a File object represents the source directory
 * @param destDir a File object represents the destination directory
 * @throws IOException thrown if IO error occurred.
 */
public static void copyDirectory(File sourceDir, File destDir)
		throws IOException {
	// creates the destination directory if it does not exist
	if (!destDir.exists()) {
		destDir.mkdirs();
	}

	// throws exception if the source does not exist
	if (!sourceDir.exists()) {
		throw new IllegalArgumentException("sourceDir does not exist");
	}

	// throws exception if the arguments are not directories
	if (sourceDir.isFile() || destDir.isFile()) {
		throw new IllegalArgumentException(
				"Either sourceDir or destDir is not a directory");
	}

	copyDirectoryImpl(sourceDir, destDir);
}

Code of the copyDirectoryImpl() method:

/**
 * Internal implementation of the copy method.
 * @param sourceDir a File object represents the source directory
 * @param destDir a File object represents the destination directory
 * @throws IOException thrown if IO error occurred.
 */
private static void copyDirectoryImpl(File sourceDir, File destDir)
		throws IOException {
	File[] items = sourceDir.listFiles();
	if (items != null && items.length > 0) {
		for (File anItem : items) {
			if (anItem.isDirectory()) {
				// create the directory in the destination
				File newDir = new File(destDir, anItem.getName());
				System.out.println("CREATED DIR: "
						+ newDir.getAbsolutePath());
				newDir.mkdir();

				// copy the directory (recursive call)
				copyDirectory(anItem, newDir);
			} else {
				// copy the file
				File destFile = new File(destDir, anItem.getName());
				copySingleFile(anItem, destFile);
			}
		}
	}
}

Code of the copySingleFile() method:

/**
 * Copy a file from a location to another
 * @param sourceFile a File object represents the source file
 * @param destFile a File object represents the destination file
 * @throws IOException thrown if IO error occurred.
 */
private static void copySingleFile(File sourceFile, File destFile)
		throws IOException {
	System.out.println("COPY FILE: " + sourceFile.getAbsolutePath()
			+ " TO: " + destFile.getAbsolutePath());
	if (!destFile.exists()) {
		destFile.createNewFile();
	}

	FileChannel sourceChannel = null;
	FileChannel destChannel = null;

	try {
		sourceChannel = new FileInputStream(sourceFile).getChannel();
		destChannel = new FileOutputStream(destFile).getChannel();
		sourceChannel.transferTo(0, sourceChannel.size(), destChannel);
	} finally {
		if (sourceChannel != null) {
			sourceChannel.close();
		}
		if (destChannel != null) {
			destChannel.close();
		}
	}
}

To test the utility class, create a program as follows:

import java.io.File;
import java.io.IOException;

/**
 * This program tests the CopyUtil class for copying a whole directory.
 * @author www.codejava.net
 *
 */
public class CopyDirectoryTest {

	public static void main(String[] args) {
		File sourceDir = new File("E:/TestCopy");
		File destDir = new File("D:/Copy");

		try {
			CopyUtil.copyDirectory(sourceDir, destDir);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}

This program will copy content of the directory E:/TestCopy to the directory D:/Copy, supposing the E:/TestCopy directory has the following structure:

 directory structure to copy

Then the test program will output the following:

copy directory test output

 

Related File IO Tutorials:

 

Other Java File IO Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (CopyDirectoryTest.java)CopyDirectoryTest.java[Test program]0.4 kB
Download this file (CopyUtil.java)CopyUtil.java[Utility class]3 kB

Add comment