IT神童

          java,net,php技術研究神童

          Java中用內存映射處理大文件

          在處理大文件時,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 來進行頻繁的讀寫操作,都將導致進程因頻繁讀寫外存而降低速度.如下為一個對比實驗。

          1. package test;  
          2.  
          3. import java.io.BufferedInputStream;  
          4. import java.io.FileInputStream;  
          5. import java.io.FileNotFoundException;  
          6. import java.io.IOException;  
          7. import java.io.RandomAccessFile;  
          8. import java.nio.MappedByteBuffer;  
          9. import java.nio.channels.FileChannel;  
          10.  
          11. public class Test {  
          12.  
          13.       
          14.     public static void main(String[] args) {  
          15.         try {  
          16.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
          17.             int sum=0;  
          18.             int n;  
          19.             long t1=System.currentTimeMillis();  
          20.             try {  
          21.                 while((n=fis.read())>=0){  
          22.                     sum+=n;  
          23.                 }  
          24.             } catch (IOException e) {  
          25.                 // TODO Auto-generated catch block  
          26.                 e.printStackTrace();  
          27.             }  
          28.             long t=System.currentTimeMillis()-t1;  
          29.             System.out.println("sum:"+sum+"  time:"+t);  
          30.         } catch (FileNotFoundException e) {  
          31.             // TODO Auto-generated catch block  
          32.             e.printStackTrace();  
          33.         }  
          34.           
          35.         try {  
          36.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
          37.             BufferedInputStream bis=new BufferedInputStream(fis);  
          38.             int sum=0;  
          39.             int n;  
          40.             long t1=System.currentTimeMillis();  
          41.             try {  
          42.                 while((n=bis.read())>=0){  
          43.                     sum+=n;  
          44.                 }  
          45.             } catch (IOException e) {  
          46.                 // TODO Auto-generated catch block  
          47.                 e.printStackTrace();  
          48.             }  
          49.             long t=System.currentTimeMillis()-t1;  
          50.             System.out.println("sum:"+sum+"  time:"+t);  
          51.         } catch (FileNotFoundException e) {  
          52.             // TODO Auto-generated catch block  
          53.             e.printStackTrace();  
          54.         }  
          55.           
          56.         MappedByteBuffer buffer=null;  
          57.         try {  
          58.             buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 01253244);  
          59.             int sum=0;  
          60.             int n;  
          61.             long t1=System.currentTimeMillis();  
          62.             for(int i=0;i<1253244;i++){  
          63.                 n=0x000000ff&buffer.get(i);  
          64.                 sum+=n;  
          65.             }  
          66.             long t=System.currentTimeMillis()-t1;  
          67.             System.out.println("sum:"+sum+"  time:"+t);  
          68.         } catch (FileNotFoundException e) {  
          69.             // TODO Auto-generated catch block  
          70.             e.printStackTrace();  
          71.         } catch (IOException e) {  
          72.             // TODO Auto-generated catch block  
          73.             e.printStackTrace();  
          74.         }  
          75.  
          76.     }  
          77.  
          78. }  
          java基礎教程
          測試文件為一個大小為1253244字節的文件。測試結果:
          1. sum:220152087 time:1464  
          2. sum:220152087 time:72  
          3. sum:220152087 time:25 

          說明讀數據無誤。刪去其中的數據處理部分。

          1. package test;  
          2.  
          3. import java.io.BufferedInputStream;  
          4. import java.io.FileInputStream;  
          5. import java.io.FileNotFoundException;  
          6. import java.io.IOException;  
          7. import java.io.RandomAccessFile;  
          8. import java.nio.MappedByteBuffer;  
          9. import java.nio.channels.FileChannel;  
          10.  
          11. public class Test {  
          12.  
          13.       
          14.     public static void main(String[] args) {  
          15.         try {  
          16.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
          17.             int sum=0;  
          18.             int n;  
          19.             long t1=System.currentTimeMillis();  
          20.             try {  
          21.                 while((n=fis.read())>=0){  
          22.                     //sum+=n;  
          23.                 }  
          24.             } catch (IOException e) {  
          25.                 // TODO Auto-generated catch block  
          26.                 e.printStackTrace();  
          27.             }  
          28.             long t=System.currentTimeMillis()-t1;  
          29.             System.out.println("sum:"+sum+"  time:"+t);  
          30.         } catch (FileNotFoundException e) {  
          31.             // TODO Auto-generated catch block  
          32.             e.printStackTrace();  
          33.         }  
          34.           
          35.         try {  
          36.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
          37.             BufferedInputStream bis=new BufferedInputStream(fis);  
          38.             int sum=0;  
          39.             int n;  
          40.             long t1=System.currentTimeMillis();  
          41.             try {  
          42.                 while((n=bis.read())>=0){  
          43.                     //sum+=n;  
          44.                 }  
          45.             } catch (IOException e) {  
          46.                 // TODO Auto-generated catch block  
          47.                 e.printStackTrace();  
          48.             }  
          49.             long t=System.currentTimeMillis()-t1;  
          50.             System.out.println("sum:"+sum+"  time:"+t);  
          51.         } catch (FileNotFoundException e) {  
          52.             // TODO Auto-generated catch block  
          53.             e.printStackTrace();  
          54.         }  
          55.           
          56.         MappedByteBuffer buffer=null;  
          57.         try {  
          58.             buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 01253244);  
          59.             int sum=0;  
          60.             int n;  
          61.             long t1=System.currentTimeMillis();  
          62.             for(int i=0;i<1253244;i++){  
          63.                 //n=0x000000ff&buffer.get(i);  
          64.                 //sum+=n;  
          65.             }  
          66.             long t=System.currentTimeMillis()-t1;  
          67.             System.out.println("sum:"+sum+"  time:"+t);  
          68.         } catch (FileNotFoundException e) {  
          69.             // TODO Auto-generated catch block  
          70.             e.printStackTrace();  
          71.         } catch (IOException e) {  
          72.             // TODO Auto-generated catch block  
          73.             e.printStackTrace();  
          74.         }  
          75.  
          76.     }  
          77.  

          測試結果:

          1. sum:0 time:1458  
          2. sum:0 time:67  
          3. sum:0 time:8 

          由此可見,將文件部分或者全部映射到內存后進行讀寫,速度將提高很多。

          這是因為內存映射文件首先將外存上的文件映射到內存中的一塊連續區域,被當成一個字節數組進行處理,讀寫操作直接對內存進行操作,而后再將內存區域重新映射到外存文件,這就節省了中間頻繁的對外存進行讀寫的時間,大大降低了讀寫時間。

          posted on 2012-08-23 14:37 IT神童 閱讀(216) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導航

          統計

          常用鏈接

          留言簿

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 桂阳县| 潼南县| 仙桃市| 阳春市| 错那县| 含山县| 宜章县| 清水河县| 平阳县| 华蓥市| 林芝县| 曲沃县| 安丘市| 阿坝县| 蓬溪县| 曲阜市| 吴川市| 安仁县| 隆昌县| 柯坪县| 宜良县| 玉溪市| 蓬莱市| 涟水县| 淮阳县| 枞阳县| 贡山| 峨眉山市| 金华市| 大石桥市| 平谷区| 中方县| 白沙| 黎川县| 富宁县| 合水县| 塘沽区| 即墨市| 苍山县| 沙洋县| 田阳县|