1. Overview
In this article, we’ll cover common ways of copying files in Java.
First, we’ll use the standard IO and NIO.2 APIs, and two external libraries: commons-io and guava.
2. IO API (Before JDK7)
First of all, to copy a file with java.io API, we’re required to open a stream, loop through the content and write it out to another stream:
@Test public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { File copied = new File("src/test/resources/copiedWithIo.txt"); try ( InputStream in = new BufferedInputStream( new FileInputStream(original)); OutputStream out = new BufferedOutputStream( new FileOutputStream(copied))) { byte[] buffer = new byte[1024]; int lengthRead; while ((lengthRead = in.read(buffer)) > 0) { out.write(buffer, 0, lengthRead); out.flush(); } } assertThat(copied).exists(); assertThat(Files.readAllLines(original.toPath()) .equals(Files.readAllLines(copied.toPath()))); }
Quite a lot of work to implement such basic functionality.
Luckily for us, Java has improved its core APIs and we have a simpler way of copying files using NIO.2 API.
3. NIO.2 API (JDK7)
Using NIO.2 can significantly increase file copying performance since the NIO.2 utilizes lower-level system entry points.
Let’s take a closer look at how the Files.copy() method works.
The copy() method gives us the ability to specify an optional argument representing a copy option. By default, copying files and directories won’t overwrite existing ones, nor will it copy file attributes.
This behavior can be changed using the following copy options:
- REPLACE_EXISTING – replace a file if it exists
- COPY_ATTRIBUTES – copy metadata to the new file
- NOFOLLOW_LINKS – shouldn’t follow symbolic links
The NIO.2 Files class provides a set of overloaded copy() methods for copying files and directories within the file system.
Let’s take a look at an example using copy() with two Path arguments:
@Test public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException { Path copied = Paths.get("src/test/resources/copiedWithNio.txt"); Path originalPath = original.toPath(); Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING); assertThat(copied).exists(); assertThat(Files.readAllLines(originalPath) .equals(Files.readAllLines(copied))); }
Note that directory copies are shallow, meaning that files and sub-directories within the directory are not copied.
4. Apache Commons IO
Another common way to copy a file with Java is by using the commons-io library.
First, we need to add the dependency:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
The latest version can be downloaded from Maven Central.
Then, to copy a file we just need to use the copyFile() method defined in the FileUtils class. The method takes a source and a target file.
Let’s take a look at a JUnit test using the copyFile() method:
@Test public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { File copied = new File( "src/test/resources/copiedWithApacheCommons.txt"); FileUtils.copyFile(original, copied); assertThat(copied).exists(); assertThat(Files.readAllLines(original.toPath()) .equals(Files.readAllLines(copied.toPath()))); }
5. Guava
Finally, we’ll take a look at Google’s Guava library.
Again, if we want to use Guava, we need to include the dependency:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency>
The latest version can be found on Maven Central.
And here’s the Guava’s way of copying a file:
@Test public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException { File copied = new File("src/test/resources/copiedWithGuava.txt"); com.google.common.io.Files.copy(original, copied); assertThat(copied).exists(); assertThat(Files.readAllLines(original.toPath()) .equals(Files.readAllLines(copied.toPath()))); }
6. Conclusion
In this article, we explored the most common ways to copy a file in Java.
The full implementation of this article can be found over on Github.