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();
    }

你可能感兴趣的:(java,nio)