<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    byterat

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      54 隨筆 :: 0 文章 :: 15 評論 :: 0 Trackbacks

    緩沖區(qū)基礎(chǔ)

    抽象類Buffer是java.nio包支持緩沖區(qū)的基礎(chǔ)。 Buffer 的工作方式就象內(nèi)存中用于讀寫基本數(shù)據(jù)類型的 RandomAccessFile 。象 RandomAccessFile 一樣,使用 Buffer ,所執(zhí)行的下一個操作(讀/寫)在當(dāng)前某個位置發(fā)生。執(zhí)行讀/寫操作中的任一個都會改變那個位置,所以在寫操作之后進行讀操作不會讀到剛才所寫的內(nèi)容,而會讀到剛才所寫內(nèi)容之后的數(shù)據(jù)。 Buffer 提供了四個指示方法,用于訪問線性結(jié)構(gòu)(從最高值到最低值):

    capacity() :表明緩沖區(qū)的容量大小, 一旦確定了大小, 將不能再改變;
    limit() :告訴您到目前為止已經(jīng)往緩沖區(qū)填了多少字節(jié),或者讓您用 :limit(int newLimit) 來改變這個限制
    position() :告訴您當(dāng)前的位置,以執(zhí)行下一個讀/寫操作
    mark() :為了稍后用 reset() 進行重新設(shè)置而記住某個位置
    flip() :交換限制指針和位置指針,然后將位置置為 0,并廢棄已經(jīng)做的mark標(biāo)記

    緩沖區(qū)的基本操作是讀 get() 和寫 put() ;然而,這些方法在子類中都是針對每種數(shù)據(jù)類型的特定方法。為了說明這一情況,讓我們研究一個簡單示例,該示例演示了從同一個緩沖區(qū)讀和寫一個字符。在清單 1 中, flip() 方法交換限制和位置,然后將位置置為 0,并廢棄標(biāo)記,讓您讀剛才所寫的數(shù)據(jù):


    清單 1. 讀/寫示例
    import java.nio.*;
    ...
    CharBuffer buff = ...;
    buff.put('A');
    buff.flip();
    char c = buff.get();
    System.out.println("An A: " + c);
     


    現(xiàn)在讓我們研究一些具體的 Buffer 子類。

     

    緩沖區(qū)類型

    Merlin 具有 7 種特定的 Buffer 類型,每種類型對應(yīng)著一個基本數(shù)據(jù)類型(不包括 boolean):

    ByteBuffer       //存放任何除boolean類型外的其他基本類型
    CharBuffer       //存放char
    DoubleBuffer     //存放double
    FloatBuffer      //存放float
    IntBuffer        //存放int
    LongBuffer       //存放long
    ShortBuffer      //存放short

    在本文后面,我將討論第 8 種類型 MappedByteBuffer ,它用于內(nèi)存映射文件。如果您必須使用的類型不是這些基本類型,則可以先從 ByteBuffer 獲得字節(jié)類型,然后將其轉(zhuǎn)換成 Object 或其它任何類型。


    創(chuàng)建緩沖區(qū)
    一共有兩種類型的緩沖區(qū),直接緩沖區(qū)和非直接緩沖區(qū)。

    在創(chuàng)建緩沖區(qū)時,可以要求創(chuàng)建直接緩沖區(qū),創(chuàng)建直接緩沖區(qū)的成本要比創(chuàng)建間接緩沖區(qū)高,但這可以使運行時環(huán)境直接在該緩沖區(qū)上進行較快的本機 I/O 操作。因為創(chuàng)建直接緩沖區(qū)所增加的成本,所以直接緩沖區(qū)只用于長生存期的緩沖區(qū),而不用于短生存期、一次性且用完就丟棄的緩沖區(qū)。而且,只能在 ByteBuffer 這個級別上創(chuàng)建直接緩沖區(qū),如果希望使用其它類型,則必須將 Buffer 轉(zhuǎn)換成更具體的類型。

    判斷一個緩沖區(qū)是否是直接緩沖區(qū),可以調(diào)用isDirect()方法。

    有三種方式來獲取一個緩沖區(qū)的對象:
    a. 調(diào)用allocate()或者allocateDirect()方法直接分配,其中allocateDirect()返回的是直接緩沖區(qū)。
    b. 包裝一個數(shù)組,如:
          byte[] b = new byte[1024];
          ByteBuffer bb = ByteBuffer.wrap(b);
    c. 內(nèi)存映射,即調(diào)用FileChannel的map()方法。

    緩沖區(qū)基本屬性
    這幾個屬性是每個緩沖區(qū)都有的并且是常用的操作。
    a. 容量(capacity),緩沖區(qū)大小
    b. 限制(limit),第一個不應(yīng)被讀取或?qū)懭氲淖止?jié)的索引,總是小于容量。
    c. 位置(position),下一個被讀取或?qū)懭氲淖止?jié)的索引,總是小于限制。
    d. clear()方法:設(shè)置limit為capacity,position為0。
    e. filp()方法:設(shè)置limit為當(dāng)前position,然后設(shè)置position為0。
    f. rewind()方法:保持limit不變,設(shè)置position為0。

    緩沖區(qū)數(shù)據(jù)操作
    操作包括了讀取和寫入數(shù)據(jù)兩種。
    讀取數(shù)據(jù)使用get()及其系列方法,除boolean外,每一種類型包括了對應(yīng)的get()方法,如getInt(),getChar()等,get()方法用來讀取字節(jié),支持相對和絕對索引兩種方式。
    寫入數(shù)據(jù)使用put()及其系列方法,和get()方法是對應(yīng)的。

    package nio;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;

    public class BufferDemo ...{

        
        public static void main(String[] args) throws Exception...{
            //分配一個非直接緩沖區(qū)
            ByteBuffer bb = ByteBuffer.allocate(100);
            //向緩沖區(qū)寫入0到100的字節(jié)制
            for(int i = 0; i <100; i++)...{
                byte b = (byte) (Math.random() * 100);
                bb.put(b);
            }
            
            System.out.println("寫入文件前的緩沖區(qū)數(shù)據(jù)");
            bb.flip();
            while(bb.hasRemaining())
                System.out.print(bb.get() + " ");
            System.out.println();
            
            //獲取一個關(guān)聯(lián)到文件buffer.txt的信道
            FileChannel fc = new FileOutputStream("buffer.txt").getChannel();
            //將緩沖區(qū)數(shù)據(jù)寫到文件中
            bb.flip();
            fc.write(bb);
            //防止緩存
            fc.force(true);
            //關(guān)閉信道
            fc.close();
            bb = null;
            fc = null;
            
            //下面從文件中讀取數(shù)據(jù)
            fc = new FileInputStream("buffer.txt").getChannel();
            ByteBuffer bb2 = ByteBuffer.allocate((int) fc.size());
            fc.read(bb2);
            System.out.println("從文件讀取的緩沖區(qū)數(shù)據(jù)");
            bb2.flip();
            while(bb2.hasRemaining())
                System.out.print(bb2.get() + " ");
            System.out.println();
            fc.close();
            bb2 = null;
            fc = null;
            

        }

    }

    內(nèi)存映射文件

    第 8 種 Buffer 類型 MappedByteBuffer 只是一種特殊的 ByteBuffer 。 MappedByteBuffer 將文件所在區(qū)域直接映射到內(nèi)存。通常,該區(qū)域包含整個文件,但也可以只映射部分文件。所以,必須指定要映射文件的哪部分。而且,與其它 Buffer 對象一樣,這里沒有構(gòu)造函數(shù);必須讓 java.nio.channels.FileChannel 的 map() 方法來獲取 MappedByteBuffer 。此外,無需過多涉及通道就可以用 getChannel() 方法從 FileInputStream 或 FileOutputStream 獲取 FileChannel 。通過從命令行傳入文件名來讀取文本文件的內(nèi)容,清單 4 顯示了 MappedByteBuffer :


    清單 4. 讀取內(nèi)存映射文本文件
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.charset.*;
    public class ReadFileBuff {
      public static void main(String args[]) throws IOException {
         if (args.length != 0) {
          String filename = args[0];
          FileInputStream fis = new FileInputStream(filename);
          FileChannel channel = fis.getChannel();
          int length = (int)channel.size();
          MappedByteBuffer byteBuffer =
            channel.map(FileChannel.MapMode.READ_ONLY, 0, length);
          Charset charset = Charset.forName("ISO-8859-1");
          CharsetDecoder decoder = charset.newDecoder();
          CharBuffer charBuffer = decoder.decode(byteBuffer);
          for (int i=0, n=charBuffer.length(); i<n; i++) {
            System.out.print(charBuffer.get());
          }
        }
      }
    }

    posted on 2007-08-01 11:13 比特鼠 閱讀(3826) 評論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 青柠影视在线观看免费高清 | 亚洲一区二区三区影院| 在线亚洲午夜片AV大片| 亚洲高清免费在线观看| 久久久无码精品亚洲日韩京东传媒 | 亚洲国产成人精品久久久国产成人一区二区三区综 | 中国性猛交xxxxx免费看| 亚洲国产精品13p| 一级毛片人与动免费观看| 亚洲精品尤物yw在线影院| 国产精品1024在线永久免费 | 亚洲性无码av在线| 99精品国产免费久久久久久下载| 亚洲六月丁香六月婷婷色伊人| 免费福利在线播放| 亚洲中文字幕一二三四区苍井空| 成年男女男精品免费视频网站| 亚洲乱码日产精品一二三| 免费人成在线观看播放国产 | 亚洲色无码国产精品网站可下载| 精品久久免费视频| xxxxx做受大片视频免费| 亚洲AV无码欧洲AV无码网站| 污污网站免费观看| 亚洲首页国产精品丝袜| 日本高清免费不卡视频| 一个人看的免费观看日本视频www| 亚洲AV无码久久寂寞少妇| 无码人妻精品中文字幕免费东京热| 亚洲中文字幕AV每天更新| 免费在线观看理论片| 免费h视频在线观看| 亚洲 欧洲 日韩 综合在线| 亚洲成av人片天堂网老年人| 免费观看久久精彩视频| 亚洲中文字幕无码爆乳| 亚洲综合无码AV一区二区 | 色播精品免费小视频| 美女被羞羞网站免费下载| 亚洲av永久无码精品秋霞电影影院| 免费观看无遮挡www的小视频|