ByteBuffer buffer = ByteBuffer.allocate(int);
ByteBuffer buffer = ByteBuffer.allocateDirect(int);
allocate返回的其實(shí)是ByteBuffer的子類HeapByteBuffer;allocateDirect返回的其實(shí)是MappedByteBuffer的子類DirectByteBuffer;
CharBuffer.allocate(int cap); 創(chuàng)建的是char[]數(shù)組,即cap是char的數(shù)量,而不是byte的數(shù)量(1個(gè)char長度為2個(gè)byte)buffer的四個(gè)屬性
0 <= mark <= position <= limit <= capacity
buffer支持級(jí)聯(lián)調(diào)用:
buffer.position(2).mark().position(4);
因?yàn)閜osition,mark方法返回的都是buffer的引用
position決定了read和write的起始位置,小于position位置的char都忽略
buffer.get() 和 buffer.put(byte) 都是相對(duì)方法,都會(huì)導(dǎo)致position++buffer.get(int) 和 buffer.put(int,byte) 都是絕對(duì)方法,不會(huì)導(dǎo)致position變化
buffer.clear() 只是將position置為0,limit設(shè)置為capacity,并不真正清空數(shù)據(jù)
buffer.position(int) 當(dāng) newPosition < mark 時(shí),丟棄mark(設(shè)置mark=-1)
buffer.mark() 將 position賦值給 mark ;buffer.reset() 將 mark 賦值給 position;buffer.remaining() 表示position到limit的數(shù)量
buffer的比較是比較position到limit之間的內(nèi)容
讀取buffer的內(nèi)容,是從position開始讀取的,并不是從0位
反轉(zhuǎn)buffer:buffer.flip();1 limit = position;2 position = 0;3 mark = -1;flip只能翻轉(zhuǎn)1次,翻轉(zhuǎn)兩次將會(huì)導(dǎo)致limit也等于0;通常用于read狀態(tài)切換到write狀態(tài),或者write狀態(tài)切換到read狀態(tài)
buffer.put(buffer) 會(huì)報(bào)IllegalArgumentException異常,因?yàn)閜osition的移動(dòng)相矛盾
buffer.slice() 用position和limit之間的內(nèi)容新生成一個(gè)buffer,該buffer的capacity為limit-position的值
charBuffer.wrap(char[], int start, int end) 將會(huì)設(shè)置positon=start,并將char[]直接傳遞給charBuffer成為內(nèi)部char array
從buffer讀取數(shù)據(jù)到數(shù)組,必須指定數(shù)據(jù)的長度:
1 buffer.remaining() < arr.length 讀取buffer的position到limit的所有值
2 buffer.remaining() > arr.length 讀取buffer中arr.length長度的值,并立即處理,然后再讀取buffer中剩余的值
從數(shù)組讀取數(shù)據(jù)到buffer:
1 buffer.remaining() > arr.length 讀取數(shù)組的所有值
2 buffer.remaining() < arr.length 拋出BufferOverflowException
buffer中多字節(jié)的數(shù)據(jù)類型存儲(chǔ)的字節(jié)順序沒有標(biāo)準(zhǔn),目前有
1 大端字節(jié)順序(BIG_ENDIAN) ,高位值在低地址(靠左側(cè)),motorola,sun,prow pc的處理器
2 小端字節(jié)順序 (LITTLE_ENDIAN),高位值在高地址(靠右側(cè)),intel處理器
這是由操作系統(tǒng)決定的,可以用ByteOrder.nativeOrder()的返回值:ByteOrder.BIG_ENDIAN 或 ByteOrder.LITTLE_ENDIAN來確定
默認(rèn)都是BIG_ENDIAN ,這是jvm決定的,所以jvm運(yùn)行在intel處理器上會(huì)有性能隱患
只有ButeBuffer可以修改字節(jié)順序,通過order()方法,除非顯式修改,否則創(chuàng)建后永不改變
其他類型的buffer可以轉(zhuǎn)換為ByteBuffer處理
直接緩沖區(qū)是IO操作的最好選擇。但并非在一開始就一定要?jiǎng)?chuàng)建。
直接緩沖區(qū)是調(diào)用操作系統(tǒng)的代碼分配的,繞開了jvm的堆棧。創(chuàng)建和銷毀的代價(jià)都比較大。
只有byteBuffer.allocateDirect()才能創(chuàng)建直接緩沖區(qū)
allocate() 和 wrap() 的包裝方法都創(chuàng)建的是非直接緩沖區(qū)(即jvm堆棧內(nèi))
ByteBuffer允許通過創(chuàng)建視圖來講byte映射為其他原始數(shù)據(jù)類型,使用asLongBuffer()等方法
ByteBuffer byteBuffer = ByteBuffer.allocate(7).order(ByteOrder.BIG_ENDIAN);
CharBuffer charBuffer = byteBuffer.asCharBuffer();
charBuffer只是一個(gè)view,只是為了方便操作,本質(zhì)上數(shù)據(jù)依舊是存放在byteBuffer中的
ByteBuffer的getInt等方法是獲取position到limit中的byte并轉(zhuǎn)換為對(duì)應(yīng)的int等數(shù)據(jù)類型
注意,不同的字節(jié)順序,取出的數(shù)值是不同的
java中的byte都是有符號(hào)的
獲取及存放無符號(hào)整數(shù)需要自己寫一個(gè)工具類:
如byte型:
buffer.put( (byte) (value & 0xff) ); 保存value的低8位的值
(short)(buffer.get() & 0xff) 取
short型:
buffer.putShort((short)(value & 0xffff));
(int)(buffer.getShort() & 0xffff);
int型:
buffer.putInt((int)(value & 0xffffffffL));
(long)(buffer.getInt() & 0xffffffffL);