NIO拷贝文件真的比IO拷贝文件效率高?

本文是基于单线程的NIO和IO拷贝文件比较, 并未对并发作测试, 请勿过分纠结场景! java

今天发现项目中有个FileUtils.copy的工具方法, 打开后发现是基于io的, 我给改为了基于NIO的, 忽然疑虑NIO拷贝文件真的如其余人说的那样比IO效率高不少么? 并发

如下是个人工具方法: dom


/**
	 * 
	 * <p>经过NIO进行文件拷贝</p>
	 * @param fromFile	被拷贝的文件
	 * @param toFile	拷贝后的文件
	 * @throws IOException 
	 */
	public static void copy(String fromFile, String toFile) throws IOException {
		FileInputStream inputStream = new FileInputStream(fromFile);
		FileChannel fromChannel = inputStream.getChannel();
		
		FileOutputStream outputStream = new FileOutputStream(toFile);
		FileChannel toChannel   = outputStream.getChannel();
		
		toChannel.transferFrom(fromChannel, 0, fromChannel.size());
//		fromChannel.transferTo(0, fromChannel.size(), toChannel);
		
		toChannel.force(true);
		inputStream.close();
		fromChannel.close();
		outputStream.close();
		toChannel.close();
	}
	
	/**
	 * 
	 * <p>使用IO拷贝文件</p>
	 * @param fromFile		被拷贝的文件
	 * @param toFile		拷贝后的文件
	 * @throws IOException
	 */
	public static void copyByIO(String fromFile, String toFile) throws IOException {
		File inputFile = new File(fromFile);
		File outputFile = new File(toFile);
		FileInputStream inputStream = new FileInputStream(inputFile);
		FileOutputStream outputStream = new FileOutputStream(outputFile);
		byte[] bytes = new byte[1024];
		int c;
		while ((c = inputStream.read(bytes)) != -1)
			outputStream.write(bytes, 0, c);
		inputStream.close();
		outputStream.close();
	}
如下是测试方法:



@Test
	//8.72M文本文件-->拷贝100次: 8781		1000次:101564
	//4.65G压缩包同文件夹拷贝1次:136160		跨盘拷贝1次:147363	
	public void testCopyNIO() {
		String from = "d:/test/test.zip";
		Long start = System.currentTimeMillis();
		try {
			for(int i=0;i<1;i++) {
				String to   = "e:/test/test"+i+".zip";
				FileUtils.copy(from, to);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		Long end = System.currentTimeMillis();
		System.out.println(end-start);
	}

	@Test
	//8.72M文本文件-->拷贝100次: 7719		1000次:109051
	//4.65G压缩包同文件夹拷贝1次:103261		跨盘拷贝1次:76799
	public void testCopyIO() {
		String from = "d:/test/test.zip";
		Long start = System.currentTimeMillis();
		try {
			for(int i=0;i<1;i++) {
				String to   = "e:/test/test"+i+".zip";
				FileUtils.copyByIO(from, to);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		Long end = System.currentTimeMillis();
		System.out.println(end-start);
	} 


第一次我找了个sysbase经过bcp命令导出的数据文件, 大小为8718KB, 使用以上两个测试方法, 分别拷贝了100次, 发现NIO执行时间为8781毫秒,IO执行时间为7719毫秒, NIO输了。 工具

第二次我将拷贝次数改为了1000, 发现NIO执行时间为101564毫秒,IO执行时间为109051毫秒, NIO赢了, 但也仅仅赢了不到8秒。 测试

第三次我将数据文件复制打包再复制再打包最后作出一个4,650,673KB大小的压缩包, 因为磁盘空间问题, 此次我只执行了1次, 发现NIO执行时间为136160毫秒,IO执行时间为103261毫秒, NIO输了33秒。 spa

我又怀疑同一个文件夹下面拷贝可能没有突出NIO的优点,因而我又作了第四次测试, 换了个磁盘, 结果发现NIO执行时间为147363毫秒,IO执行时间为76799毫秒, NIO输了更惨, 耗费时间足足是IO的两倍。 线程

可见NIO虽然在不少方面比IO强,可是这也并非绝对的。 code

以上只是针对NIO和普通IO的简单测试, 并无深究文件拷贝, 有兴趣的兄弟能够去研究下经过BufferedInputStream和RandomAccessFile来进行文件拷贝。其中RandomAccessFile效率应该和FileInputStream差很少, BufferedInputStream确定比其余的要高效不少。 ip

相关文章
相关标签/搜索