A simple set of tests found that Java NIO provides the file memory mapping method to achieve the fastest file copy, whether large files or small files, especially large files copy speed than the normal method to improve 20 times times, the only prerequisite is that the memory needs large enough, Otherwise, the file mappings will fail (of course, by splitting the file, the partial mapping method avoids, but is more troublesome; Secondly, NIO provides file pipeline transmission speed is also relatively good, if can not do file memory mapping, recommend this copy method; In addition, the size of the buffer, the speed of reading and writing is still influential, The basic thing is that the larger the buffer, the faster the read and write (there is a question is buffer.allocatedirec () efficiency is not obvious); Finally, NIO is more efficient than old IO in general, regardless of the way in which the old IO uses the stream to read and write only one byte of a byte to pull, NIO uses blocks to read or write relatively fast, so it is recommended to use NIO in the absence of special requirements, and NiO is now basically able to cover all the features of the old Io (and, of course, NiO also offers n-many new features).
Test environment
Eclipse (Juno) JVM (Sun JDK1.7) parameter:
-xms1536m
-xmx1536m
-xverify:none-xx:+useparallelgc
-xx: permsize=128m
-xx:maxpermsize=128m
os parameters:
Win7 64Bit + 4GB
Physical disk space sufficient
Test code
Import Java.io.FileInputStream;
Import java.io.FileNotFoundException;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.RandomAccessFile;
Import Java.nio.ByteBuffer;
Import Java.nio.MappedByteBuffer;
Import Java.nio.channels.FileChannel;
public class FileCopy {private static final int buffer_size_1024 = 1024;
private static final int buffer_size_4096 = 4096;
private static final int buffer_size_10240 = 10240;
private static final String FROM_FILE_42MB = "G:/from_42mb.rar";
private static final String FROM_FILE_1GB = "G:/from_350mb.rar";
private static int buffer_size = buffer_size_1024;
private static String from_file = FROM_FILE_42MB;
/** * @param args * @throws Exception/public static void main (string[] args) throws Exception {
System.out.println ("File:" + from_file + "----Buffer Size:" + buffer_size + "--------------");
Testfilecopy (); Buffer_size = buffer_size_4096;
System.out.println ("File:" + from_file + "----Buffer Size:" + buffer_size + "--------------");
Testfilecopy ();
Buffer_size = buffer_size_10240;
System.out.println ("File:" + from_file + "----Buffer Size:" + buffer_size + "--------------");
Testfilecopy ();
Buffer_size = buffer_size_1024;
From_file = FROM_FILE_1GB;
System.out.println ("File:" + from_file + "----Buffer Size:" + buffer_size + "--------------");
Testfilecopy ();
Buffer_size = buffer_size_4096;
From_file = FROM_FILE_1GB;
System.out.println ("File:" + from_file + "----Buffer Size:" + buffer_size + "--------------");
Testfilecopy ();
Buffer_size = buffer_size_10240;
From_file = FROM_FILE_1GB; System.out.println ("File:" + from_file + "----Buffer Size:" + buffer_size + "--------------");
Testfilecopy ();
private static void Testfilecopy () throws FileNotFoundException, IOException {COYPBYMBB ();
Copybyniotransferfrom ();
Copybyniotransferto ();
Coypbybufferread ();
Coypbyfastbufferread ();
Coypbystream ()//old IO style}/** * uses Filechannel.transferfrom () to implement * @throws FileNotFoundException
* @throws IOException */private static void Copybyniotransferfrom () throws FileNotFoundException,
IOException {Long starttime = System.currenttimemillis ();
Randomaccessfile fromfile = new Randomaccessfile (from_file, "RW");
FileChannel Fromchannel = Fromfile.getchannel ();
Randomaccessfile tofile = new Randomaccessfile ("G:/to1.rar", "RW");
FileChannel Tochannel = Tofile.getchannel ();
Long position = 0;
Long Count = Fromchannel.size (); Tochannel.transferfrom (Fromchannel, POSItion, Count);
Long endtime = System.currenttimemillis (); System.out.println ("Copybyniotransferfrom time consumed (buffer size no effect):" + (Endtime-starttime)
);
/** * Use Filechannel.transferto () to implement * @throws FileNotFoundException * @throws IOException * * private static void Copybyniotransferto () throws FileNotFoundException, IOException {long starttime =
System.currenttimemillis ();
Randomaccessfile fromfile = new Randomaccessfile (from_file, "RW");
FileChannel Fromchannel = Fromfile.getchannel ();
Randomaccessfile tofile = new Randomaccessfile ("G:/to2.rar", "RW");
FileChannel Tochannel = Tofile.getchannel ();
Long position = 0;
Long Count = Fromchannel.size ();
Fromchannel.transferto (position, count, Tochannel);
Long endtime = System.currenttimemillis (); System.out.println ("Copybyniotransferto Time consumed" (buffer size no effect) : "+ (Endtime-starttime)); /** * Using channel, buffer simple Read and write implementation * @throws IOException * * private static void Coypbybufferread () thr
oWS IOException {Long starttime = System.currenttimemillis ();
FileInputStream fin = new FileInputStream (from_file);
FileOutputStream fout = new FileOutputStream ("G:/to3.rar");
FileChannel fcin = Fin.getchannel ();
FileChannel fcout = Fout.getchannel ();
Bytebuffer buffer = bytebuffer.allocate (buffer_size);
while (true) {buffer.clear ();
int r = fcin.read (buffer);
if (r = = 1) {break;
} buffer.flip ();
Fcout.write (buffer);
Long endtime = System.currenttimemillis ();
System.out.println ("Coypbybufferread time consumed (buffer size take effect):" + (Endtime-starttime));
/** * Using continuous memory buffer to implement * @throws IOException * * private static void Coypbyfastbufferread () throws IOException {Long starttime = System.currenttimemillis
();
FileInputStream fin = new FileInputStream (from_file);
FileOutputStream fout = new FileOutputStream ("G:/to4.rar");
FileChannel fcin = Fin.getchannel ();
FileChannel fcout = Fout.getchannel ();
Bytebuffer buffer = Bytebuffer.allocatedirect (buffer_size);
while (true) {buffer.clear ();
int r = fcin.read (buffer);
if (r = = 1) {break;
} buffer.flip ();
Fcout.write (buffer);
Long endtime = System.currenttimemillis (); System.out.println ("Coypbyfastbufferread time consumed (buffer size take effect):" + (Endtime-starttime
));
/** * Using a file memory map to implement * @throws IOException * * private static void Coypbymbb () throws IOException { Long starttime = System.currenttimemillis ();
FileInputStream fin = new FileInputStream (from_file);
Randomaccessfile fout = new Randomaccessfile ("G:/to5.rar", "RW");
FileChannel fcin = Fin.getchannel ();
FileChannel fcout = Fout.getchannel ();
Mappedbytebuffer Mbbi = Fcin.map (FileChannel.MapMode.READ_ONLY, 0, Fcin.size ());
Mappedbytebuffer Mbbo = Fcout.map (FileChannel.MapMode.READ_WRITE, 0, Fcin.size ());
Mbbo.put (Mbbi);
Mbbi.clear ();
Mbbo.clear ();
Long endtime = System.currenttimemillis ();
System.out. println ("COYPBYMBB time consumed (buffer size no effect):" + (Endtime-starttime)); /** * Using traditional IO streaming read-write mode * @throws IOException/private static void Coypbystream () throws Ioexcepti
On {Long starttime = System.currenttimemillis ();
FileInputStream fin = new FileInputStream (from_file);
FileOutputStream fout = new FileOutputStream ("G:/to6.rar"); byte[] buffer = new Byte[buffer_size];
while (true) {int ins = fin.read (buffer);
if (ins = = 1) {fin.close ();
Fout.flush ();
Fout.close ();
Break
} else{fout.write (buffer, 0, INS);
} Long Endtime = System.currenttimemillis ();
System.out.println ("Coypbystream time consumed (buffer size take effect):" + (Endtime-starttime)); }
}