java利用“對應檔訪問”(MapperByteBuffer)處理檔案與單純利用Buffer來處理檔案的快慢比較,bytebuffer

來源:互聯網
上載者:User

java利用“對應檔訪問”(MapperByteBuffer)處理檔案與單純利用Buffer來處理檔案的快慢比較,bytebuffer

  處理檔案是java經常使用的操作,在對一個“大檔案”(比如超過64M)進行操作時一點點速度的提高都會帶來效能的巨大提升。然而我們經常使用的BufferxxStream,來直接處理大檔案時,往往力不從心。

  java中“對應檔訪問”機制則解決了這一問題,它把大檔案的較小部分先放在記憶體裡,將其餘待讀取的資料仍然放在硬碟裡面。但是我們完全可以通過這樣一個機制把這個大檔案當作非常大的數組來使用。是不是很像作業系統裡面對於應用的使用方法?沒錯,其實java正是利用了底層作業系統的檔案對應工具來最大化提高效能。

  一般為了即能讀又能寫,我們使用RandomAccessFile來進行測試,同過該檔案上的通道,然後調用FileChannel中的map()所產生的MappedByteBuffer,在map方法中有三個參數map(FileChannel.MapMode mode, long position, long size)。

  其中mode 來決定映射的檔案訪問的讀/寫機制,可以設定MapMode.READ_ONLY, MapMode.READ_WRITE,MapMode.PRIVATE,通過名字可以看得出他們的作用,特別要注意MapMode.PRIVATE方法,如何你操作不當會導致你操作的檔案無法被共用。

  而position為地區內的檔案對應的位置開始,必須是非負數

   size為地區的大小是映射;必須是非負數,不大於Integer.MAX_VALUE

  其實position和size的設定就意味著我們映射某個大檔案的較小的部分

  下面就來看我們使用了“對應檔訪問”時,的效能提升把!

 

  以下是代碼部分:

  1 package com.company;  2   3 import java.io.*;  4 import java.nio.IntBuffer;  5 import java.nio.channels.FileChannel;  6   7 /**  8  * Created by chunmiao on 17-3-15.  9  */ 10 public class MappedIOTest { 11     //輸入值的數量 12     private static int numOfInts = 4000000; 13     //測試讀寫值的數量大小 14     private static int numOfUbuffInts = 200000; 15  16     private abstract static class Tester{ 17         private String name; 18         public Tester(String name){ 19             this.name = name; 20         } 21  22         //測試計時 23         public void runTest(){ 24             System.out.println(name + ": "); 25             try { 26                 long start = System.nanoTime(); 27                 test(); 28                 long runtime = System.nanoTime() - start; 29                 //輸出test()已耗用時間,來判定操作時間大小 30                 System.out.format("%.2f\n",runtime/1.0e9); 31             }catch (IOException e){ 32                 throw new RuntimeException(e); 33             } 34         } 35  36         public abstract void test() throws IOException; 37     } 38  39     private static Tester[] tests = { 40             //直接寫入資料 41             new Tester("Stream Write") { 42                 @Override 43                 public void test() throws IOException { 44                     DataOutputStream dos = new DataOutputStream( 45                             new BufferedOutputStream( 46                                     new FileOutputStream(new File("temp.tmp")))); 47                     for (int i = 0; i < numOfInts; i ++){ 48                         dos.writeInt(i); 49                     } 50                     dos.close(); 51                 } 52             }, 53             //使用MappedByteBuffer進行寫檔案操作 54             new Tester("Mapped Write") { 55                 @Override 56                 public void test() throws IOException { 57                     FileChannel fc = new RandomAccessFile("temp.tmp","rw").getChannel(); 58                     //fc.size()返回的是以byte為單位的數量值。 59                     IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE,0,fc.size()).asIntBuffer(); 60                     for(int i =0 ; i < numOfInts ; i ++){ 61                         try { 62                             ib.put(i); 63                         }catch (Exception e){ 64                             System.out.println(i); 65                         } 66                     } 67                     fc.close(); 68                 } 69             }, 70             //直接讀資料 71             new Tester("Stream Read") { 72                 @Override 73                 public void test() throws IOException { 74                     DataInputStream dis = new DataInputStream( 75                             new BufferedInputStream(new FileInputStream("temp.tmp"))); 76                     for (int i = 0 ; i < numOfInts ; i ++){ 77                         dis.readInt(); 78                     } 79                     dis.close(); 80                 } 81             }, 82             //使用MappedByteBuffer進行讀檔案操作 83             new Tester("Mapped Read") { 84                 @Override 85                 public void test() throws IOException { 86                     FileChannel fc = new FileInputStream(new File("temp.tmp")).getChannel(); 87                     IntBuffer ib = fc.map(FileChannel.MapMode.READ_ONLY,0,fc.size()).asIntBuffer(); 88                     while (ib.hasRemaining()){ 89                         ib.get(); 90                     } 91                     fc.close(); 92                 } 93             }, 94             //直接進行讀/寫操作 95             new Tester("Stream Read/Write") { 96                 @Override 97                 public void test() throws IOException { 98                     RandomAccessFile raf = new RandomAccessFile(new File("temp.tmp"),"rw"); 99                     //對資料進行進行錯位,以便同時進行讀寫操作100                     raf.writeInt(1);101                     for (int i = 0 ; i < numOfUbuffInts ; i ++){102                         //之所以減4的原因是raf.length()返回以byte為單位的空間大小,而1 (int) = 4 (byte),因此需要減4103                         raf.seek(raf.length() - 4);104                         raf.writeInt(raf.readInt());105                     }106                     raf.close();107                 }108             },109             //使用MappedByteBuffer進行讀/寫操作110             new Tester("Mapped Read/Write") {111                 @Override112                 public void test() throws IOException {113                     FileChannel fc = new RandomAccessFile(new File("temp.tmp"),"rw").getChannel();114                     IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE,0,fc.size()).asIntBuffer();115                     ib.put(0);116                     for (int i = 1 ; i < numOfUbuffInts ; i ++){117                         //對資料進行進行錯位,以便同時進行讀寫操作118                         ib.put(ib.get(i - 1));119                     }120                     fc.close();121                 }122             }123     };124 125     public static void main(String[] args) {126         //進行測試127         for (Tester tester : tests){128             tester.runTest();129         }130     }131 }

以下是運行結果:

 

   

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.