How to copy directory in Java
In Java, we can use the Java 1.7 FileVisitor
or Apache Commons IO FileUtils.copyDirectory
to copy a directory, which includes its sub-directories and files.
This article shows a few of the common ways to copy a directory in Java.
FileVisitor
(Java 7+)FileUtils.copyDirectory
(Apache commons-io)- Custom Copy using Java 7 NIO and Java 8 Stream.
- Custom Copy, legacy IO.
Note
The NIO Files.copy
does not support copying directory contents, and we need to create a customized method to copy the directory contents.
1. FileVisitor (Java 7)
This example shows how to use FileVisitor to copy directory and its content from /home/mkyong/test/
to /home/mkyong/test2/
.
$ tree /home/mkyong/test
test
├── test-a1.log
├── test-a2.log
└── test-b
├── test-b1.txt
├── test-b2.txt
├── test-c
│ ├── test-c1.log
│ └── test-c2.log
└── test-d
├── test-d1.log
└── test-d2.log
1.1 This class extends SimpleFileVisitor
to provide defaults and override only necessary methods.
package com.mkyong.io.utils;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class TreeCopyFileVisitor extends SimpleFileVisitor<Path> {
private Path source;
private final Path target;
public TreeCopyFileVisitor(String source, String target) {
this.source = Paths.get(source);
this.target = Paths.get(target);
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
Path resolve = target.resolve(source.relativize(dir));
if (Files.notExists(resolve)) {
Files.createDirectories(resolve);
System.out.println("Create directories : " + resolve);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Path resolve = target.resolve(source.relativize(file));
Files.copy(file, resolve, StandardCopyOption.REPLACE_EXISTING);
System.out.println(
String.format("Copy File from \t'%s' to \t'%s'", file, resolve)
);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.err.format("Unable to copy: %s: %s%n", file, exc);
return FileVisitResult.CONTINUE;
}
}
1.2 This example uses Files.walkFileTree
to walk the file tree.
package com.mkyong.io.howto;
import com.mkyong.io.utils.TreeCopyFileVisitor;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class CopyDirectory1 {
public static void main(String[] args) {
String fromDirectory = "/home/mkyong/test/";
String toToDirectory = "/home/mkyong/test2/";
try {
copyDirectoryFileVisitor(fromDirectory, toToDirectory);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Done");
}
public static void copyDirectoryFileVisitor(String source, String target)
throws IOException {
TreeCopyFileVisitor fileVisitor = new TreeCopyFileVisitor(source, target);
Files.walkFileTree(Paths.get(source), fileVisitor);
}
}
Output
Create directories : /home/mkyong/test2
Copy File from '/home/mkyong/test/test-a2.log' to '/home/mkyong/test2/test-a2.log'
Copy File from '/home/mkyong/test/test-a1.log' to '/home/mkyong/test2/test-a1.log'
Create directories : /home/mkyong/test2/test-b
Copy File from '/home/mkyong/test/test-b/test-b1.txt' to '/home/mkyong/test2/test-b/test-b1.txt'
Create directories : /home/mkyong/test2/test-b/test-c
Copy File from '/home/mkyong/test/test-b/test-c/test-c2.log' to '/home/mkyong/test2/test-b/test-c/test-c2.log'
Copy File from '/home/mkyong/test/test-b/test-c/test-c1.log' to '/home/mkyong/test2/test-b/test-c/test-c1.log'
Copy File from '/home/mkyong/test/test-b/test-b2.txt' to '/home/mkyong/test2/test-b/test-b2.txt'
Create directories : /home/mkyong/test2/test-b/test-d
Copy File from '/home/mkyong/test/test-b/test-d/test-d2.log' to '/home/mkyong/test2/test-b/test-d/test-d2.log'
Copy File from '/home/mkyong/test/test-b/test-d/test-d1.log' to '/home/mkyong/test2/test-b/test-d/test-d1.log'
Done
Check the new directory.
$ tree /home/mkyong/test2
test2
├── test-a1.log
├── test-a2.log
└── test-b
├── test-b1.txt
├── test-b2.txt
├── test-c
│ ├── test-c1.log
│ └── test-c2.log
└── test-d
├── test-d1.log
└── test-d2.log
Note
The official Java Copy example copies everything, including the file attribute. However, it is harder to read; this example simplifies the method to only copy files and directories and excludes the attributes.
2. FileUtils.copyDirectory (Apache commons-io)
This example uses FileUtils.copyDirectory
to copy a directory and its content, a friendly, and straightforward API.
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
import org.apache.commons.io.FileUtils;
//...
public static void copyFileCommonIO(String from, String to)
throws IOException {
File fromDir = new File(from);
File toDir = new File(to);
FileUtils.copyDirectory(fromDir, toDir);
}
3. Java NIO and Stream.
This example uses Java 8 Files.list
to simulate a file walker and Java 7 NIO Files
to check, create, and copy the directory and its content.
package com.mkyong.io.howto;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;
public class CopyDirectory3 {
public static void main(String[] args) {
String fromDirectory = "/home/mkyong/test/";
String toToDirectory = "/home/mkyong/test2/";
try {
copyDirectoryJavaNIO(Paths.get(fromDirectory),
Paths.get(toToDirectory));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Done");
}
public static void copyDirectoryJavaNIO(Path source, Path target)
throws IOException {
// is this a directory?
if (Files.isDirectory(source)) {
//if target directory exist?
if (Files.notExists(target)) {
// create it
Files.createDirectories(target);
System.out.println("Directory created : " + target);
}
// list all files or folders from the source, Java 1.8, returns a stream
// doc said need try-with-resources, auto-close stream
try (Stream<Path> paths = Files.list(source)) {
// recursive loop
paths.forEach(p ->
copyDirectoryJavaNIOWrapper(
p, target.resolve(source.relativize(p)))
);
}
} else {
// if file exists, replace it
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println(
String.format("Copy File from \t'%s' to \t'%s'", source, target)
);
}
}
// extract method to handle exception in lambda
public static void copyDirectoryJavaNIOWrapper(Path source, Path target) {
try {
copyDirectoryJavaNIO(source, target);
} catch (IOException e) {
System.err.println("IO errors : " + e.getMessage());
}
}
}
4. Legacy IO
This example is similar to method 3. Instead, it sticks with the legacy IO java.io.*
, just for reference.
package com.mkyong.io.howto;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;
public class CopyDirectory4 {
public static void main(String[] args) {
String fromDirectory = "/home/mkyong/test/";
String toToDirectory = "/home/mkyong/test2/";
try {
copyDirectoryLegacyIO(
new File(fromDirectory),
new File(toToDirectory));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Done");
}
public static void copyDirectoryLegacyIO(File source, File target)
throws IOException {
if (source.isDirectory()) {
//if directory not exists, create it
if (!target.exists()) {
if (target.mkdir()) {
System.out.println("Directory copied from "
+ source + " to " + target);
} else {
System.err.println("Unable to create directory : " + target);
}
}
// list all the directory contents, file walker
String[] files = source.list();
if (files == null) {
return;
}
for (String file : files) {
//construct the src and dest file structure
File srcFile = new File(source, file);
File destFile = new File(target, file);
//recursive copy
copyDirectoryLegacyIO(srcFile, destFile);
}
} else {
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(source);
out = new FileOutputStream(target);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
System.out.println("File copied from " + source + " to " + target);
} catch (IOException e) {
System.err.println("IO errors : " + e.getMessage());
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
}
Note
Java, after 20+ years, there is still no official API to copy a directory, how hard to create a Files.copyDirectory()
?
Download Source Code
$ git clone https://github.com/mkyong/core-java
$ cd java-io
thank you….
FileUtils.copyDirectory(lSrc, lDest);
This could also serve better.
Simple and faster.
Hope this helps.
Article is updated with the Apache common-io API, thanks.
I am having the following error:- Could not find or load the main class CopyDirectory
Thanks man! This is very helpful!
Thank you so much Buddy.
Very useful code. very handy
Prem Pratick Kumar
Thank you a lot you helps me.
Hi mkyong,
There is any way of Cut & Paste in same Directory like Windows do (only changing path if same directory)
Hi mkyong,
Thanks for this piece of code. It really is useful.
Regards,
Tejas
The code wont’t work if the destination folder is changed to c:\\mkyong-new\\NewfolderA
How do we test the copying on directory using JUnit?
I am using FileUtils of Apache Commons IO API.
Please explain.
The code works great but if it has to be copied from one server to another, having a try catch block when copying would be beneficial
Hi, Thanks for this. Can you let me know how to copy directories and files from one server to another server
Thanks so much for this. I needed to empty my destination directory before copying to restore it to a controlled condition, so I modified your code to make an additional utility to do that. Here it is.
Thanks for your additional inputs
To be resolved in Java 7 (hopefully, and at last!)
http://openjdk.java.net/projects/nio/presentations/TS-5686.pdf
For copying files, FileChannel.transferTo() is much faster.
If there’s an error, I usually exit with an error code different than 0. This way you could check for it in a script, or other program.
Hi, why don’t you use an existing API like the apache commons IO FileUtils?
Some suggestions for your code:
Never use System.exit(). I can’t remember a case where it’s actually needed.
Better use mkdirs instead of mkdir to create a directory if you’re not sure that the parent directories do already exist. And check the return value. Sometimes it will return false. You may throw an IOException in this case.
File.list may return null. Better check for it.
Always use try-finally when dealing with resource which have to be closed. If an error occurs in your code while copying the files, the streams remain open and my cause you problems afterwards.
This is a demonstration to show the use of pure Java to copy a whole directory, good for practice and learning purpose only.
In production, the common FileUtils should be always recommended, and your suggestions will definitely bring much extra values for this article. Thanks and appreciate your sharing.
C:\demo\myfile1.txt,myfile.txt,myfile2.txt,myfile3.txt………….
C:\demo2\myfile1.txt,myfile.txt,myfile2.txt,myfile3.txt………….
here demo and demo2 are child directories which have same files but different data ,i want to merge (demo)myfile1+(demo2)myfile1 and create a file myfile1 at parent directory c:\demo3 please help