?對比較大的而不能放入內存的文件進行I/O操作時,如果使用NIO中的內存映射文件對性能效率和速度的提高是非常顯著的。首先需要獲取文件的通道,然后調用通道的map(FileChannel.MapMode mode,long position,long size)函數將文件從position位置開始的長度為size的內容映射到內存中。具體的效率比較代碼示例如下:
?
- import ?java.io.BufferedInputStream;??
- import ?java.io.BufferedOutputStream;??
- import ?java.io.DataInputStream;??
- import ?java.io.DataOutputStream;??
- import ?java.io.FileInputStream;??
- import ?java.io.FileOutputStream;??
- import ?java.io.IOException;??
- import ?java.io.RandomAccessFile;??
- import ?java.nio.IntBuffer;??
- import ?java.nio.channels.FileChannel;??
- ??
- //測試代碼是借用thingking?in?java中的 ??
- public ? class ?MappedIO?{??
- ??????
- ???? //先聲明需要寫入的文件的內容的大小 ??
- ???? private ? static ? final ? int ?NUMOFINT= 4000000 ;??
- ???? private ? static ? final ? int ?NUMOFOUT= 2000000 ;??
- ??????
- ???? //測試類,用來測試使用普通的I/O操作和使用內存文件映射時速度的差別 ??
- ???? abstract ? static ? class ?Tester{??
- ???????? private ?String?name;??
- ???????? public ?Tester(String?name){??
- ???????????? this .name=name;??
- ????????}??
- ??????????
- ???????? public ? void ?runTest(){??
- ????????????System.out.println( "使用" +name+ "所消耗的時間:" );??
- ???????????? try {??
- ???????????? //以毫微秒為單位獲取測試函數開始前的時間 ??
- ???????????? long ?begin=System.nanoTime();??
- ??????????????
- ????????????test();??
- ???????????? //將測試函數結束后的系統的時間減去開始之前的時間獲取 ??
- ???????????? double ?duration=System.nanoTime()-begin;??
- ???????????? //PrintStream中的使用指定格式字符串和參數將格式化字符串寫入此輸出流中的方法 ??
- ????????????System.out.format( "%.2f\n" ,?duration/ 1 .0e9);??
- ????????????} catch (IOException?e){??
- ????????????????e.printStackTrace();??
- ????????????}??
- ????????}??
- ??????????
- ???????? //具體的測試函數中其實不僅有對文件進行讀取或寫入的時間,還包括消耗的各種初始化I/O對象的時間,而且內存映射文件的初始化對象消耗更要比普通的操作大 ??
- ???????? public ? abstract ? void ?test()? throws ?IOException;??
- ????}??
- ??????
- ???? private ? static ?Tester[]?tests={??
- ???????? //先使用普通的stream?write,并且還是用了Buffered緩沖 ??
- ???????? new ?Tester( "stream?write" ){??
- ???????????? public ? void ?test() throws ?IOException{??
- ????????????????DataOutputStream?dos= new ?DataOutputStream( new ?BufferedOutputStream( new ?FileOutputStream( "baolei.txt" )));???
- ???????????????? for ( int ?i= 0 ;i<NUMOFINT;i++){??
- ????????????????????dos.writeInt(i);??
- ????????????????}??
- ????????????????dos.close();??
- ????????????}??
- ????????},??
- ???????? //使用內存映射文件方式寫入文件時的測試內部類 ??
- ???????? new ?Tester( "mapped?write" ){??
- ???????????? public ? void ?test()? throws ?IOException{??
- ???????????????? //利用RandomAccessFile初始化文件獲取通道 ??
- ????????????????FileChannel?fc= new ?RandomAccessFile( "baolei.txt" , "rw" ).getChannel();??
- ???????????????? //利用IntBuffer基本類型視圖緩沖器來修改底層的ByteBuffer,實際上ByteBuffer是將數據移進移出通道的唯一方式 ??
- ????????????????IntBuffer?ib=fc.map(FileChannel.MapMode.READ_WRITE,? 0 ,fc.size()).asIntBuffer();??
- ???????????????? for ( int ?i= 0 ;i<NUMOFINT;i++){??
- ????????????????????ib.put(i);??
- ????????????????}??
- ??????????????????
- ????????????????fc.close();??
- ????????????}??
- ????????},??
- ??????????
- ???????? //下面的兩個測試方法是測試read文件時的速度,基本和上面的兩個一樣 ??
- ???????? new ?Tester( "stream?read" ){??
- ???????????? public ? void ?test() throws ?IOException{??
- ????????????????DataInputStream?dis= new ?DataInputStream( new ?BufferedInputStream( new ?FileInputStream( "baolei.txt" )));??
- ??????????????????
- ???????????????? for ( int ?i= 0 ;i<NUMOFOUT;i++){??
- ????????????????????dis.readInt();??
- ????????????????}??
- ????????????????dis.close();??
- ????????????}??
- ????????},??
- ???????? new ?Tester( "mapped?read" ){??
- ???????????? public ? void ?test()? throws ?IOException{??
- ????????????????FileChannel?fc= new ?RandomAccessFile( "baolei.txt" , "rw" ).getChannel();??
- ????????????????IntBuffer?ib=fc.map(FileChannel.MapMode.READ_WRITE,? 0 ,?fc.size()).asIntBuffer();??
- ???????????????? while (ib.hasRemaining()){??
- ????????????????????ib.get();??
- ????????????????}??
- ??????????????????
- ????????????????fc.close();??
- ????????????}??
- ????????}??
- ??
- ????};??
- ??????
- ???? public ? static ? void ?main(String[]?args){??
- ???????? for (Tester?test:tests){??
- ????????????test.runTest();??
- ????????}??
- ????}??
- ??
- }??
?
?? 可以看到運行后的結果如下:
????????? ?使用stream write所消耗的時間:
?????????? 0.92
????????? 使用mapped write所消耗的時間:
?????????? 0.12?
????????? 使用stream read所消耗的時間:
?????????? 0.50
???????? 使用mapped read所消耗的時間:
?????????? 0.06
??? 效率確實大幅度提高啊。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
