夢幻之旅

          DEBUG - 天道酬勤

             :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            671 隨筆 :: 6 文章 :: 256 評論 :: 0 Trackbacks
          在 NIO 庫中,所有數據都是用緩沖區處理的。在讀取數據時,它是直接讀到緩沖區中的。在寫入數據時,它是寫入到緩沖區中的。任何時候訪問 NIO 中的數據,都是將它放到緩沖區中。緩沖區實質上是一個數組。通常它是一個字節數組,但是也可以使用其他種類的數組。但是一個緩沖區不僅僅是一個數組。緩沖區提供了對數據的結構化訪問,而且還可以跟蹤系統的讀/寫進程。

          buffer其實只是一個美化了的數組。

          狀態變量
          跟蹤數據的狀態情況使buffer可以自己管理數據資源 

          position: 其實是指從buffer讀取或寫入buffer的下一個元素位置。比如,已經寫入buffer 3個元素那那么position就是指向第4個位置,即position設置為3(數組從0開始計)。
          limit:還有多少數據需要從buffer中取出,或還有多少空間可以放入。postition總是
          <=limit。
          capacity: 表示buffer本身底層數組的容量。limit絕不能
          >capacity。
          filp():作了兩件事情:
          1.將limit指向現在position的位置 2.將position設置為0 (limit=position;position=0
                 這個過程可以使之前buffer寫入數據時改變的狀態變為可以“準備讀取”。因為之前寫到buffer中的數據就是position 到 limit
          -1 兩個位置之間(limit指向最后一個數據的后一個位置)。

          clear():
              也作了兩件事:
          1. limit=capacity 2.position=0
          這個過程可以使buffer讀取數據時改變的狀態改變為“清空并準備寫入”。

          訪問方法
          以下都以bytebuffer為例
          get():
             前三個get方法是相對讀取。就是相對于位置狀態來讀取數據,并且會改變position位置狀態。
             
          byte get();
             ByteBuffer get(
          byte dst[]);//讀取bytebuffer中數據寫入 dst[]
             ByteBuffer get(byte dst[],int offset, int length);
             
             該讀取數據是絕對讀取(一個byte),即會忽略limit和position值。并完全繞過了緩沖區的狀態統計方法。
             就是說不會改變buffer內部的位置狀態。
             
          byte get(int index);
           
          put();
             與get類似 前四個put方法是相對讀取。即受position 以及limit影響,并且會改變 position。
             ByteBuffer put( 
          byte b );
             ByteBuffer put( 
          byte src[] ); //從src[]寫入bytebuffer
             ByteBuffer put( byte src[], int offset, int length );
             ByteBuffer put( ByteBuffer src );
             最后一個是絕對寫入 不會影響position等位置狀態。
             ByteBuffer put( 
          int index, byte b );
           
          除了byte的讀寫還有其他類型的讀寫方法。并且他們都存在相對以及絕對兩類。
           
          操作的典型使用:
          view plaincopy to clipboardprint
          ?while (true{  
               buffer.clear(); 
          // 準備將數據寫入buffer   
               int r = fcin.read( buffer ); // channel讀取外部系統的數據并寫入 buffer   
               if (r==-1{  
                 
          break;  
               }
            
               buffer.flip(); 
          //準備將數據讀出buffer   
               fcout.write( buffer ); // channel讀取buffer的數據并寫到相應的外部系統   
          }
            
          while (true{
               buffer.clear(); 
          // 準備將數據寫入buffer
               int r = fcin.read( buffer ); // channel讀取外部系統的數據并寫入 buffer
               if (r==-1{
                 
          break;
               }

               buffer.flip(); 
          //準備將數據讀出buffer
               fcout.write( buffer ); // channel讀取buffer的數據并寫到相應的外部系統
          }
           
          高級應用
          緩存區的分配和包裝
          ByteBuffer.allocate(
          int);方法可以分配(創建)一個byte類型的buffer。
          ByteBuffer.wrap(
          byte[]);方法可以將一個已有的byte數組包裝出一個新的bytebuffer對象。
          后一種方式需要小心處理原來的那個byte數組。因為它可以直接訪問了。
          緩沖區的分片
          分片就是建立“子緩沖區”。子緩沖區共享父緩沖區的一部分底層數組位置。
          在某種意義上,子緩沖區就像原來的緩沖區中的一個窗口。
          這樣當改變子緩沖區的內容時,父緩沖區的相應位置也會被改變。
          分片操作是根據當前position以及limit的值來確定的。
          buffer.position( 
          3 );
          buffer.limit( 
          7 );
          ByteBuffer slice 
          = buffer.slice();
          只讀緩沖區
          asReadOnlyBuffer()方法可以返回一個與原buffer對象一樣的對象,只是新的buffer對象是只讀的。
          直接緩沖區
          sun的定義:給定一個直接字節緩沖區,Java 虛擬機將盡最大努力直接對它執行本機 I
          /O 操作。也就是說,它會在每一次調用底層操作系統的本機 I/O 操作之前(或之后),嘗試避免將緩沖區的內容拷貝到一個中間緩沖區中(或者從一個中間緩沖區中拷貝數據)。
          創建directbuffer的方式是用ByteBuffer.allocateDirect( 
          int );方法替代ByteBuffer.allocate(int);
          內存影射文件I
          /O
          它讀寫要比其他IO快很多.
          他使文件或文件的一部分由內存影射。但是只有操作該部分位置的數據才是以內存方式讀寫的,而不是整個文件讀入內存。(并且他是一個os的底層機制。由os底層異步完成內存與物理磁盤上的數據同步)
          影射文件可以通過FileChannel對象的map方法得到。
          比如以下就是將一個文件的前1024個字節影射到內存,并創建一個MappedByteBuffer對象返回出來。MappedByteBuffer是ByteBuffer的一個子類。
          MappedByteBuffer mbb 
          = fc.map( FileChannel.MapMode.READ_WRITE, start, size );
          posted on 2011-09-04 19:27 HUIKK 閱讀(2310) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 武川县| 芮城县| 本溪| 扎鲁特旗| 三门县| 南部县| 宜宾县| 栾川县| 中西区| 宁安市| 长垣县| 南丰县| 扎赉特旗| 德令哈市| 五台县| 白水县| 微山县| 察哈| 加查县| 宁国市| 育儿| 广东省| 泰宁县| 上思县| 景东| 微博| 濉溪县| 祁东县| 怀安县| 凤庆县| 阳城县| 奉新县| 济阳县| 龙游县| 微山县| 平邑县| 镇赉县| 通州区| 息烽县| 孝昌县| 蒙城县|