Java实现文件拷贝 推荐
2013-08-14 16:58
330 查看
经过一组简单的测试发现JAVA NIO提供的文件内存映射方法实现文件拷贝速度最快,不管是大文件还是小文件,特别是大文件的拷贝速度比普通方法提高20倍,唯一有个前提就是内存需要足够大,否则文件映射肯定失败(当然可以通过分割文件,部分映射的方法避免,但就比较麻烦了);其次NIO提供的文件管道传输速度也比较好,如果没法做文件内存映射,推荐这种拷贝方法;另外,Buffer的大小,对于读写速度还是有影响的,基本就是Buffer越大读写越快(有个疑问就是Buffer.allocateDirec()效率提高不明显);最后,总体看来NIO的效率比老IO高,不管使用哪种方式,老IO使用流读写只能一个字节一个字节的抠,NIO使用块的方式读写还是相对比较快,所以没有特别需求的情况下,推荐使用NIO,目前NIO基本能覆盖老IO的所有功能(当然NIO还提供N多新功能)。
测试环境
测试代码
测试环境
Eclipse(Juno) JVM(Sun JDK1.7) 参数: -Xms1536m -Xmx1536m -Xverify:none -XX:+UseParallelGC -XX:PermSize=128M -XX:MaxPermSize=128M OS参数: Win7 64Bit + 4GB 物理磁盘空间充足
测试代码
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 } /** * 使用FileChannel.transferFrom()实现 * @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)); } /** * 使用FileChannel.transferTo()实现 * @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)); } /** * 使用Channel, Buffer简单读写实现 * @throws IOException */ private static void coypByBufferRead() throws 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)); } /** * 使用连续内存的Buffer实现 * @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)); } /** * 使用文件内存映射实现 * @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)); } /** * 使用传统IO的流读写方式实现 * @throws IOException */ private static void coypByStream() throws IOException { 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)); } }测试结果
File :G:/from_42MB.rar ---- Buffer Size : 1024-------------- coypByMbb time consumed(buffer size no effect) : 47 copyByNioTransferFrom time consumed(buffer size no effect) : 62 copyByNioTransferTo time consumed(buffer size no effect) : 47 coypByBufferRead time consumed(buffer size take effect) : 249 coypByFastBufferRead time consumed(buffer size take effect) : 188 coypByStream time consumed(buffer size take effect) : 187 File :G:/from_42MB.rar ---- Buffer Size : 4096-------------- coypByMbb time consumed(buffer size no effect) : 15 copyByNioTransferFrom time consumed(buffer size no effect) : 16 copyByNioTransferTo time consumed(buffer size no effect) : 31 coypByBufferRead time consumed(buffer size take effect) : 125 coypByFastBufferRead time consumed(buffer size take effect) : 79 coypByStream time consumed(buffer size take effect) : 93 File :G:/from_42MB.rar ---- Buffer Size : 10240-------------- coypByMbb time consumed(buffer size no effect) : 16 copyByNioTransferFrom time consumed(buffer size no effect) : 32 copyByNioTransferTo time consumed(buffer size no effect) : 31 coypByBufferRead time consumed(buffer size take effect) : 78 coypByFastBufferRead time consumed(buffer size take effect) : 62 coypByStream time consumed(buffer size take effect) : 63 File :G:/from_350MB.rar ---- Buffer Size : 1024-------------- coypByMbb time consumed(buffer size no effect) : 280 copyByNioTransferFrom time consumed(buffer size no effect) : 453 copyByNioTransferTo time consumed(buffer size no effect) : 7785 coypByBufferRead time consumed(buffer size take effect) : 8144 coypByFastBufferRead time consumed(buffer size take effect) : 7068 coypByStream time consumed(buffer size take effect) : 8503 File :G:/from_350MB.rar ---- Buffer Size : 4096-------------- coypByMbb time consumed(buffer size no effect) : 1904 copyByNioTransferFrom time consumed(buffer size no effect) : 5978 copyByNioTransferTo time consumed(buffer size no effect) : 7379 coypByBufferRead time consumed(buffer size take effect) : 7621 coypByFastBufferRead time consumed(buffer size take effect) : 7474 coypByStream time consumed(buffer size take effect) : 8200 File :G:/from_350MB.rar ---- Buffer Size : 10240-------------- coypByMbb time consumed(buffer size no effect) : 328 copyByNioTransferFrom time consumed(buffer size no effect) : 6864 copyByNioTransferTo time consumed(buffer size no effect) : 7021 coypByBufferRead time consumed(buffer size take effect) : 7199 coypByFastBufferRead time consumed(buffer size take effect) : 7941 coypByStream time consumed(buffer size take effect) : 7801
相关文章推荐
- Java实现文件拷贝的4种方法.
- Java实现文件拷贝的4种方法.
- java实现文件以及文件夹拷贝的几种方式
- Java实现文件拷贝的4种方法(转)
- [编写高质量代码:改善java程序的151个建议]建议43 避免对象浅拷贝; 建议44:推荐使用序列化实现对象的深拷贝
- java实现文件拷贝
- 用java实现文件的拷贝
- Java实现文件拷贝
- java实现文件拷贝!
- Java IO与NIO实现文件拷贝
- java文件复制代码片断(java实现文件拷贝)
- Java实现文件拷贝的4种方法
- Java实现文件拷贝的4种方法
- Java实现文件拷贝的4种方法
- JavaIO实现文件的拷贝
- java 实现指定文件的复制和 拷贝
- java实现拷贝文件到另一个路径
- java实现文件拷贝(复制)
- Java如何实现文件拷贝操作和如何正确关闭资源
- Java实现文件拷贝的4种方法