Copying a file means creating a duplicate file at some other location. Copying involves reading a file and writing its contents to a new location.
This article will explain 7 different ways to copy a file in java with examples.

1. Using input and output streams

Use a java.io.InputStream to read a file.
Read the file using its read() method. This method accepts a byte array as argument, reads the file and places the data read into this byte array.
read() returns the number of bytes read or -1 if there are no bytes left to read. Thus, loop till read() method returns -1 and in every iteration, write the contents of the byte array to an output stream. Example,

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileCopyExample {
   public static void main(String[] args) throws IOException {
      String sourceFilePath = "E:/Test/demo.xml";
      String targetPath = "E:/Test/nested/demo.xml";
      File sourceFile = new File(sourceFilePath);
      File targetFile = new File(targetPath);
      InputStream inputStream = null;
      OutputStream outputStream = null;
      try {
         // initialize input and output streams
         inputStream = new FileInputStream(sourceFile);
         outputStream = new FileOutputStream(targetFile);
         byte[] buffer = new byte[1024];
         int numberOfBytes = 0;
         // read file
         while ((numberOfBytes = inputStream.read(buffer)) != -1) {
           // write content
           outputStream.write(buffer);
         }
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         // close streams
         if (inputStream != null) {
   	   inputStream.close();
         }
         if (outputStream != null) {
           outputStream.close();
         }
      }
   }
}

Since java.io.InputStream is an abstract class, you need to create an object of java.io.FileInputStream which is its child class. Similar is the case with java.io.OutputStream.
This method can be used to copy text file as well as binary files such as images, songs, video, keystore files etc.

2. Using FileReader

java.io.FileReader class can be used to reading a file.
It has a read() method which accepts a char[] as argument, reads the file content into this array and returns -1 when there is no content to read.

Loop over read() method till it returns -1 and in every iteration, write the contents of char array using java.io.FileWriter class.
This class has a write() method which takes a character array as argument and writes it to a file. Example,

import java.io.FileReader;
import java.io.FileWriter;
import java.io.File;

public class FileCopyExample {
   public static void main(String[] args) throws IOException {
      String sourceFilePath = "E:/Test/demo.xml";
      String targetPath = "E:/Test/nested/demo.xml";
      File sourceFile = new File(sourceFilePath);
      File targetFile = new File(targetPath);
      FileReader reader = null;
      FileWriter writer = null;
      try {
        // initialize reader and writer
        reader = new FileReader(sourceFile);
        writer = new FileWriter(targetFile);
        // array to hold file contents
        char[] buffer = new char[1024];
        int numberOfBytes = 0;
        // read file
        while ((numberOfBytes = reader.read(buffer)) != -1) {
          // write content
          writer.write(buffer);
        }
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        // close reader and writer
        if (reader != null) {
   	  reader.close();
        }
        if (writer != null) {
          writer.close();
        }
      }
   }
}

Note that java.io.FileReader and java.io.FileWriter classes are concrete classes, hence you can directly create their objects using new operator.
This method can only be used to copy text files but not binary files.

3. Using BufferedReader

This method is similar to the above method in that it can also be used to read only text files.
Above method would read the file on a character by character basis while this method can read the file line by line.

java.io.BufferedReader class has a readLine method which reads a line of file at a time. This method returns null if there is nothing to read.
Similarly, java.io.BufferedWriter class has a write method which accepts a String as argument. Output of by readLine method can be supplied to the write method. Example,

import java.io.FileReader;
import java.io.FileWriter;
import java.io.File;
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
public class FileCopyExample {
   public static void main(String[] args) throws IOException {
     String sourceFilePath = "E:/Test/demo.xml";
     String targetPath = "E:/Test/nested/demo.xml";
     File sourceFile = new File(sourceFilePath);
     File targetFile = new File(targetPath);
     FileReader reader = null;
     FileWriter writer = null;
     BufferedReader bReader = null
     try {
       // initialize reader
       reader = new FileReader(sourceFile);
       // initialize buffered reader
       bReader = new BufferedReader(reader);
       // initialize writer
       writer = new FileWriter(targetFile);
       // initialize buffered writer
       bWriter = new BufferedWriter(reader);           
       // array to hold file contents
       String line = null;
       // read file line by line
       while ((line = bReader.readLine()) != -1) {
         // write content
         bWriter.write(line);
       }
     } catch (FileNotFoundException e) {
       e.printStackTrace();
     } catch (IOException e) {
       e.printStackTrace();
     } finally {
       // close reader and writer
       if (bReader != null) {
   	 bReader.close();
       }
       if (bWriter != null) {
         bWriter.close();
       }
     }
   }
}

java.io.BufferedReader is a wrapper around a reader. Thus, you need to supply a java.io.FileReader object while creating its object. File reader object points to the actual file as shown above.
Similarly, java.io.BufferedWriter accepts an object of java.io.FileWriter which points to the actual file written.

4. Using java 7 nio

java.nio.file.Files class was added in java 7 and belongs to java.nio package. It has a copy method which takes two arguments of type java.nio.file.Path representing the source and destination files.
Below is an example program to copy file from one location to another in java.

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileCopyExample {
   public static void main(String[] args) throws IOException {
      String sourceFilePath = "E:/Test/demo.xml";
      String targetPath = "E:/Test/nested/demo.xml";
      // create path object
      Path sourcePath = Paths.get(sourceFilePath);
      Path targetPath = Paths.get(targetFilePath);
      // copy file
      Files.copy(sourcePath, targetPath);
   }
}

5. Using Apache Commons IO

Apache Commons IO Library has org.apache.commons.io.FileUtils class having a copyFile() method.
This method takes two java.io.File objects as arguments which represent the source and destination files respectively and copies the file. Example,

import java.io.File;
import org.apache.commons.io.FileUtils;

public class FileCopyExample {
   public static void main(String[] args) throws IOException {
      String sourceFilePath = "E:/Test/demo.xml";
      String targetPath = "E:/Test/nested/demo.xml";
      // create file objects
      File sourceFile = new File(sourceFilePath);
      File targetFile = new File(targetPath);
      // copy file
      FileUtils.copyFile(sourceFile, targetFile);
   }
}

For adding Apache Commons Library to your project, add the following dependency as per the build tool being used.

<!– Maven –>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>

// Gradle
compile group: ‘org.apache.commons’, name: ‘commons-io’, version: ‘1.3.2’

6. Using Guava Library

Guava library has a class com.google.common.io.Files having a copy() method.
This method accepts two arguments of type java.io.File, one representing the source file and second is the destination file.

import java.io.File;
import com.google.common.io.Files;

public class FileCopyExample {
   public static void main(String[] args) throws IOException {
      String sourceFilePath = "E:/Test/demo.xml";
      String targetPath = "E:/Test/nested/demo.xml";
      // create file objects
      File sourceFile = new File(sourceFilePath);
      File targetFile = new File(targetPath);
      // copy file
      Files.copy(sourceFile, targetFile);
   }
}

In all the above methods, it is not necessary to create the copied file with the same name, you can also change the name of destination file.
In order to use this library, add a dependency as per the build tool below.

<!– Maven –>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>

// Gradle
compile group: ‘com.google.guava’, name: ‘guava’, version: ‘28.1-jre’

Conclusion

You can choose any of the above methods to copy file from one location to another as per the requirement.

If the files are binary, then go with streams.
If the file to be copied is a text file and your project allows you to use external libraries, then go with Apache Commons or Guava, otherwise use java nio or Reader classes.

Leave a Reply