现在的位置: 首页 > 综合 > 正文

NIO与普通IO文件读写性能对比

2018年05月24日 ⁄ 综合 ⁄ 共 1723字 ⁄ 字号 评论关闭

    最近在熟悉java的nio功能。nio采用了缓冲区的方式进行文件的读写,这一点更接近于OS执行I/O的方式。写了个新旧I/O复制文件的代码,练练手,顺便验证一下两者读写性能的对比,nio是否真的比普通I/O更快了。

    拿来测试复制性能的文件是104MB的视频文件,测试代码如下:

package nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

public class NioTest {

	/**
	 * test
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		String infile = "F:\\乱扯逼的西游记.flv";
		String outfile = "F:\\a.flv";
		String outfile2 = "F:\\a1.flv";
		
		long start = System.currentTimeMillis();
		nioCopy(infile, outfile);
		long end1 = System.currentTimeMillis();
		normalCopy(infile, outfile2);
		long end2 = System.currentTimeMillis();
		
		System.out.println("nio copy lasts: " + (end1 - start));
		System.out.println("normal copy lasts: " + (end2 - end1));
	}
	
	//nio文件复制功能
	public static void nioCopy(String infile, String outfile) throws Exception {
		FileInputStream fin = new FileInputStream(infile);
		FileOutputStream fout = new FileOutputStream(outfile);
		FileChannel fcin = fin.getChannel();
		FileChannel fcout = fout.getChannel();
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		
		while (true) {
			buffer.clear();
			int r = fcin.read(buffer);
			if (r == -1) {
				break;
			}
			buffer.flip();
			fcout.write(buffer);
		}
		
		fcin.close();
		fcout.close();
		fin.close();
		fout.close();
	}
	
	//普通I/O文件复制功能
	public static void normalCopy(String infile, String outfile) throws Exception{
		FileInputStream fin = new FileInputStream(infile);
		FileOutputStream fout = new FileOutputStream(outfile);
		byte[] block = new byte[1024];
		while(fin.read(block) != -1) {
			fout.write(block);
		}
		fin.close();
		fout.close();
	}

}

    测试结果如下:

    得到这个结果的时候,很震惊!NIO居然更慢,而且慢了400ms。查阅《java编程思想》,书中解释,JDK1.4引入了nio之后,旧的I/O代码也由nio包重新实现过了。但是nio复制文件也不应该慢400ms啊!本来想通过源码的方式排查问题,但是nio读写方法在找实现时,eclipse提示我更换源码包。找普通I/O读写实现的时候,一直追踪到了native方法声明便戛然而止,可能是调用了更底层的C语言的fread,fwrite方法吧。


抱歉!评论已关闭.