最近在深入学习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(); }