程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java實現文件拷貝的測試

Java實現文件拷貝的測試

編輯:關於JAVA

經過一組簡單的測試發現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

出處:http://stevex.blog.51cto.com/4300375/1272956

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved