1. 程式人生 > >NIO(零拷貝,非零拷貝) 與IO 進行檔案的copy

NIO(零拷貝,非零拷貝) 與IO 進行檔案的copy

最近在深入學習java NIO ,把自己的一些體會分享出來,

總結,java NIO效率要高於 java IO,而java nio 零拷貝操作效率要高於 非零拷貝操作,具體程式碼如下:

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;


public class StreamCopyFile {

    public static final int SIZE = 10000 ;

    /** 間接copy
     * 間接NIO copy 耗時為:4.937s
     * 間接
NIO copy 耗時為:3.971s * @param fis * @param fos * @return */ public static boolean indirectCopyFile(FileInputStream fis, FileOutputStream fos) throws IOException { long l1 = System.currentTimeMillis(); FileChannel srcFileChannel = fis.getChannel(); FileChannel targetFileChannel = fos.getChannel(); //
間接獲取ByteBuffer ByteBuffer byteBuffer = ByteBuffer.allocate(SIZE); while(true) { byteBuffer.clear(); int readByte = srcFileChannel.read(byteBuffer); if(readByte == -1) { break; } byteBuffer.flip(); targetFileChannel.write(byteBuffer); } long
l2 = System.currentTimeMillis(); System.out.println("間接NIO copy 耗時為:"+(l2-l1)/1000.0 +"s"); return true; }
    /** 直接copy
     *  直接NIO copy 耗時為:3.727s
     * @param fis
* @param fos
* @return
*/
public static boolean directCopyFile(FileInputStream fis, FileOutputStream fos) throws IOException {
        long l1 = System.currentTimeMillis();
        FileChannel srcFileChannel = fis.getChannel();
        FileChannel targetFileChannel = fos.getChannel();
        //間接獲取ByteBuffer
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(SIZE);
        while(true) {
            byteBuffer.clear();
            int readByte = srcFileChannel.read(byteBuffer);
            if(readByte == -1) {
                break;
            }
            byteBuffer.flip();
            targetFileChannel.write(byteBuffer);
        }
        long l2 = System.currentTimeMillis();
        System.out.println("直接NIO copy 耗時為:"+(l2-l1)/1000.0 +"s");
        return true;
    }
/** 利用channl transferTo 方法效率最高
* 間接NIO copy 耗時為:4.937s
 * 間接NIO copy 耗時為:3.971s
 * @param fis
* @param fos
* @return
*/
public static boolean copyFileByTransferTo(FileInputStream fis, FileOutputStream fos) throws IOException {
    long l1 = System.currentTimeMillis();
    FileChannel srcFileChannel = fis.getChannel();
    FileChannel targetFileChannel = fos.getChannel();
    System.out.println(srcFileChannel.size());
    srcFileChannel.transferTo(0,srcFileChannel.size(),targetFileChannel);
    long l2 = System.currentTimeMillis();
    System.out.println("transferTo 耗時為:"+(l2-l1)/1000.0 +"s");
    return true;
}
/** IO 間接copy * io copy 耗時為:5.621s copy result : true * io copy 耗時為:3.727s * @param fis* @param fos* @return*/public static boolean copyFile(FileInputStream fis, FileOutputStream fos) throws IOException { long l1 = System.currentTimeMillis(); byte [] byteArr = new byte[SIZE]; while(true) { int len = fis.read(byteArr); if(len == -1) { break; } fos.write(byteArr); } long l2 = System.currentTimeMillis(); System.out.println("io copy 耗時為:"+(l2-l1)/1000.0 +"s"); return true; }
    public static void main(String[] args) throws Exception {

//        FileInputStream fis = new FileInputStream("D:/temp/解密區塊鏈核心密碼學1.mp4");
FileInputStream fis = new FileInputStream("D:/temp/ebook.rar");
        File targetFile1 = new File("d:/temp/test1.rar");
        File targetFile2 = new File("d:/temp/test2.mp4");
        File targetFile3 = new File("d:/temp/test3.mp4");
        if(!targetFile1.exists()) {
            targetFile1.createNewFile();
        }
        if(!targetFile2.exists()) {
            targetFile2.createNewFile();
        }
        if(!targetFile3.exists()) {
            targetFile3.createNewFile();
        }
        FileOutputStream fos1 = new FileOutputStream(targetFile1);
        FileOutputStream fos2 = new FileOutputStream(targetFile2);
        FileOutputStream fos3 = new FileOutputStream(targetFile3);
//        boolean b = copyFile(fis,fos);
//        boolean b = indirectCopyFile(fis,fos);
//        boolean b3 = directCopyFile(fis,fos3);
//        boolean b2 = indirectCopyFile(fis,fos2);
//        boolean b1 = copyFile(fis,fos1);
boolean b1 = indirectCopyFile(fis,fos1);
//        System.out.println("copy result b1 : "+b1+",b2 : "+b2+",b3 : "+b3);
fis.close();
        fos1.close();
        fos2.close();
        fos3.close();
    }