JAVA NIO Buffer

你曾是少年就是我發表於2019-03-26

Buffer的基本用法

  1. 寫入資料到Buffer
  2. 呼叫flip()方法
  3. 從Buffer中讀取資料
  4. 呼叫clear()方法或者compact()方法
    當向buffer寫入資料時,buffer會記錄寫下了多少資料
    一旦要讀取資料,需要通過filp()方法將buffer從寫模式切換到讀模式
    在讀模式下,可以讀取之前寫入到buffer的所有資料
    一旦讀完了所有的資料,就需要清空緩衝區,讓它可以再次被寫入
    有兩種方式可以清空緩衝區:clear()和compact()方法
    clear()方法會清空整個緩衝區
    compact()方法只會清除已經讀過的資料,任何未讀的資料都被移到緩衝區的起始處,新寫入的資料將放到緩衝區未讀資料的後面

Buffer的capacity,position和limit

緩衝區本質上是一塊可以寫入資料,然後可以從中讀取資料的記憶體 buffer有重要的三個屬性capacity,position和limit
position和limit的含義取決於Buffer處在讀模式還是寫模式。不管Buffer處在什麼模式,capacity的含義總是一樣的

JAVA NIO Buffer

capacity

作為一個記憶體塊,Buffer有一個固定的大小值,就是capacity,你只能往裡寫capacity個byte、long,char等型別。一旦Buffer滿了,需要將其清空(通過讀資料或者清除資料)才能繼續寫資料往裡寫資料。

position

當你寫資料時,position表示當前的位置,初始的position值為0,當一個資料寫到buffer後,position會向前移動到下一個可插入資料的buffer位置,position最大可為capacity – 1
當你讀資料時,也是從某個位置去讀,當buffer呼叫filp()方法從寫模式切換到讀模式時,position會被重置為0,當從Buffer的position處讀取資料時,position會移動到下一個可讀的位置

limit

在寫模式下,limit和capacity一樣,表示最多可以寫多少的資料
在讀模式下,limit表示最多可以讀的資料當buffer呼叫filp()方法從寫模式切換到讀模式時,limit會被設定成寫模式下的position值

Buffer的方法說明

Buffer的分配

每一個Buffer類都有一個allocate方法
ByteBuffer buf = ByteBuffer.allocate(48) 分配48位元組capacity的ByteBuffer
CharBuffer buf = CharBuffer.allocate(1024) 分配一個可儲存1024個字元的CharBuffer

向Buffer中寫入資料

有兩種方式

  1. 從Channel寫到Buffer int bytesRead = inChannel.read(buf)
  2. 通過Buffer的put()方法寫到Buffer裡 buf.put(127)

flip()方法

lip方法將Buffer從寫模式切換到讀模式。呼叫flip()方法會將position設回0,並將limit設定成之前position的值

從Buffer中讀取資料

從Buffer中讀取資料也有兩種方式

  1. 從buffer讀取資料到channel int bytesWritten = inChannel.write(buf)
  2. 使用get()方法從Buffer中讀取資料 byte aByte = buf.get()

rewind()方法

public final Buffer rewind() {
        position = 0;
        mark = -1;
        return this;
    }
複製程式碼

將position設回0,所以你可以重讀Buffer中的所有資料。limit保持不變,仍然表示能從Buffer中讀取多少個元素

mark()與reset()方法

public final Buffer mark() {
        mark = position;
        return this;
    }
    
public final Buffer reset() {
        int m = mark;
        if (m < 0)
            throw new InvalidMarkException();
        position = m;
        return this;
    }    
複製程式碼

通過呼叫Buffer.mark()方法,可以標記Buffer中的一個特定position。之後可以通過呼叫Buffer.reset()方法恢復到這個position

相關文章