Java copy file is a very common operation. But java.io.File class doesn’t have any shortcut method to copy a file from source to destination. Here we will learn about four different ways we can copy file in java.
This is the conventional way of file copy in java. Here we create two Files - source and destination. Then we create InputStream from source and write it to the destination file using OutputStream for java copy file operation. Here is the method that can be used for java copy file using streams.
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
Java NIO classes were introduced in Java 1.4 and FileChannel can be used to copy file in java. According to transferFrom() method javadoc, this way of copy file is supposed to be faster than using Streams for java copy files. Here is the method that can be used to copy a file using FileChannel.
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
Apache Commons IO FileUtils.copyFile(File srcFile, File destFile) can be used to copy file in java. If you are already using Apache Commons IO in your project, it makes sense to use this for code simplicity. Internally it uses Java NIO FileChannel, so you can avoid this wrapper method if you are not already using it for other functions. Here is the method for using apache commons io for java copy file operation.
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
If you are working on Java 7 or higher, you can use Files class copy() method to copy file in java. It uses File System providers to copy the files.
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
Now to find out which is the fastest method, I wrote a test class and executed above methods one-by-one for copy file of 1 GB. In each call, I used different files to avoid any benefit to later methods because of caching.
package com.journaldev.files;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
public class JavaCopyFile {
public static void main(String[] args) throws InterruptedException, IOException {
File source = new File("/Users/pankaj/tmp/source.avi");
File dest = new File("/Users/pankaj/tmp/dest.avi");
//copy file conventional way using Stream
long start = System.nanoTime();
copyFileUsingStream(source, dest);
System.out.println("Time taken by Stream Copy = "+(System.nanoTime()-start));
//copy files using java.nio FileChannel
source = new File("/Users/pankaj/tmp/sourceChannel.avi");
dest = new File("/Users/pankaj/tmp/destChannel.avi");
start = System.nanoTime();
copyFileUsingChannel(source, dest);
System.out.println("Time taken by Channel Copy = "+(System.nanoTime()-start));
//copy files using apache commons io
source = new File("/Users/pankaj/tmp/sourceApache.avi");
dest = new File("/Users/pankaj/tmp/destApache.avi");
start = System.nanoTime();
copyFileUsingApacheCommonsIO(source, dest);
System.out.println("Time taken by Apache Commons IO Copy = "+(System.nanoTime()-start));
//using Java 7 Files class
source = new File("/Users/pankaj/tmp/sourceJava7.avi");
dest = new File("/Users/pankaj/tmp/destJava7.avi");
start = System.nanoTime();
copyFileUsingJava7Files(source, dest);
System.out.println("Time taken by Java7 Files Copy = "+(System.nanoTime()-start));
}
}
Here is the output of the above program, note that I commented above code to make sure every time only one method is used for java file copy operation.
Time taken by Stream Copy = 44582575000
Time taken by Channel Copy = 104138195000
Time taken by Apache Commons IO Copy = 108396714000
Time taken by Java7 Files Copy = 89061578000
From the output, it’s clear that Stream Copy is the best way to copy File in Java. But it’s a very basic test. If you are working on a performance intensive project, then you should try out different methods for java copy file and note down the timings to figure out the best approach for your project. You should also play around different ways of java copy files based on your average size of the file. I have created a YouTube video for 4 ways to copy the file in java, you can watch it to learn more. https://www.youtube.com/watch?v=op6tgG95zek
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Hi I have a problem how can help me ? I want to code a server socket with create ,copy and delete file method but i dont know what to do .
- Laila
private static void copyFileUsingStream(File source, File dest) throws IOException { InputStream is = null; OutputStream os = null; try { is = new FileInputStream(source); os = new FileOutputStream(dest); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); // Vulnerability(stored XSS) is detected at this line. } } finally { is.close(); os.close(); } }
- Security
It has been touched on before in the comment above, but when you determine the read/write buffer size, I found that you better stick with at least 64K (65536) due to that being the largest NTFS cluster size (4kb default, also in most other file systems). In fact, it’s even faster with normal I/O streams if you go by Megabyte - you can reach 150 Mb/s on fast disks/RAID arrays in spindles, and more on SSD. The Java 7 copyFile method looks nice, but you loose control over e.g. influencing the bandwidth, if you want to throttle copying, which you can do by calculating the milliseconds you want for 1Mb, for example, and wait out the rest of those milliseconds if you’re faster. This will allow for not slowing down a work system. Also, instead of copying when inside the same file system (disk/raid array/NFS mount/CIFS mount) in Java 7 you can hardlink instead, saving space (useful for separate play lists of media).
- Olaf Leimann
import java.util.*; import java.io.*; class FILE4 { public static void main(String args[])throws Exception { Scanner s1=new Scanner(System.in); FileOutputStream f1=new FileOutputStream(“E:/A2.txt”,true); DataOutputStream d1=new DataOutputStream(f1); char choice; int rno; String name; do { System.out.println(“Enter a roll number and name:”); rno=s1.nextInt(); name=s1.nextLine(); d1.writeInt(rno); d1.writeUTF(name); System.out.println(“Continue???”); choice=s1.next().charAt(0); }while(choice==‘y’||choice==‘Y’); System.out.println(“DO YOU WANT TO READ THIS BINARY FILE??\nIF YES THEN TYPE ‘YES’ OTHERWISE TYPE ‘NO’—>”); String ch=s1.next(); if(ch.equalsIgnoreCase(“yes”)) { try { FileInputStream F1=new FileInputStream(“E:/A2.txt”); DataInputStream D1=new DataInputStream(F1); boolean eof=true; while(eof) { try { int rn=D1.readInt(); String nm=D1.readUTF(); System.out.println("ROLL NO. “+rn+”\nNAME "+nm); } catch(EOFException x) { eof=false; } } } catch(FileNotFoundException e) { System.out.println(“File Does Not Found”); } } if(ch.equalsIgnoreCase(“No”)) { System.out.println(“Byeee!!!”); System.exit(0); } FileOutputStream F=new FileOutputStream(“E:/A3.txt”,true); DataOutputStream D=new DataOutputStream(F); boolean e=true; try { FileInputStream F1=new FileInputStream(“E:/A2.txt”); DataInputStream D1=new DataInputStream(F1); while(e) { int rns=D1.readInt(); String nms=D1.readUTF(); D.writeInt(rns); D.writeUTF(nms); } } catch(EOFException x) { e=false; } System.out.println(“DO YOU WANT TO READ THE COPIED BINARY FILE??\nIF YES THEN TYPE ‘YES’ OTHERWISE TYPE ‘NO’—>”); String ch1=s1.next(); if(ch.equalsIgnoreCase(“yes”)) { try { FileInputStream F12=new FileInputStream(“E:/A3.txt”); DataInputStream D12=new DataInputStream(F12); boolean eof=true; while(eof) { try { int rnI=D12.readInt(); String nmI=D12.readUTF(); System.out.println("ROLL NO. “+rnI+”\nNAME "+nmI); } catch(EOFException x) { eof=false; } } } catch(FileNotFoundException x) { System.out.println(“File Does Not Found”); } } if(ch.equalsIgnoreCase(“No”)) { System.out.println(“Byeee!!!”); System.exit(0); } } }
- Ana
Hi! Replace > with >= in copyFileUsingStream; while ((length = is.read(buffer)) >= 0)
- Harri
There is an error in your FileChannel example, since one call to transferFrom is not guaranteed to be sufficient - it should be in a loop.
- Zarquon
I am sorry I have to say this is misleading. 1. First benchmark on files highly depends on filesystem and disk type you’re using. Assume you are using buffer for all code, streaming may be faster. But if your filesystem supports DMA, Java may use DMA in FileChannel.transferTo/transferFrom, this maybe much faster than using streaming.
- Haibo Yan
good
- Trần Phú
How to write a multithreaded java program which opens a USB drive (flash drive) automatically after it is plugged into the machine, scans all files in the disk, and copy content each file to corresponding files in the local disk simultaneously. Thanks for your help.
- Eyosiyas
Thank you very much.
- Ngọc Khương