本文是基於單線程的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