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

相關文章
相關標籤/搜索