然而,當我們需要對磁盤上的文件進行處理的時候,這是壹個很重要的方法。在這個時候我們往往不得不自己實現這樣壹個完成文件復制操作的方法。下面將會介紹4種常見的文件復制的實現,並比較下它們的性能。
能找到的最常見經典例子。從文件A的輸入流讀取壹批字節,寫到文件B的輸出流。
如妳所見,這種實現方式需要多次讀取數據,再寫入將數據寫入,因此受限於我們提供的buffer的大小,他的效率有點壹般。
Java NIO類庫裏引入了壹個叫 transferFrom 的方法,文檔裏說這是壹個會比 FileStream 方式更快的復制操作。
Appache Commons IO 提供了壹個 FileUtils.copyFile(File from, File to) 方法用於文件復制,如果項目裏使用到了這個類庫,使用這個方法是個不錯的選擇。它的內部也是使用Java NIO的 FileChannel 實現的。
如果對Java 7 的使用有經驗的話,那應該接觸過 Files 這個工具類。
由於項目裏沒用到 Apache Common IO ,Android僅支持 Java 7 的語法特性,因此我只測試了前兩種,數據如下:
復制文件,大小2M
復制文件,大小4.5M
復制文件,大小8M
復制文件,大小161M
從數據上可以看出,使用 FileStream 的方式,復制的效率跟我們的buffer大小取值關系很大,這無疑加大了我們使用它進行文件復制的負擔。
而NIO的方式則不然,無論是小文件、還是大文件,它的效率都跟我們測試 FileStream 的最好水平相當!
因此,把 FileStream 這種老舊的實現方式從項目裏挪走吧,是時候用上 FileChannel 了。
2016年06月16日 14:04 更新
大致就是從輸入裏映射壹部分作為buffer,寫到輸出去,Buffer的大小最大為8388608,如果剩余的文件長度小於這個值,則用剩余文件長度的大小為buffer大小,繼續寫入,直到完全寫完。
需要註意到的是,buffer並不是我們平時使用的byte數組,而是 MappedByteBuffer 對象,這是 java nio 引入的文件內存映射方案,讀寫性能很高。