天天看点

java缓冲区总结笔记

缓冲区的三个重要属性

容量(capacity):缓冲区的大小,是一个不能改变的值。

极限(limit):一个可以设定的值,设定之后,缓冲区只有前这么多个位置(索引号为[0,limit-1])是可见的,后面的部分都是不可见的。

当前位置(position):当前如果进行读写操作的话将会读写的位置。只能读写缓冲区的可见部分。

标记(mark):和输入流的标记一样,也是标记当前位置,将来可以令position与之对齐,从标记位置开始读写。

显然,有0 <= mark <= position <= limit <= capacity.

缓冲区族的继承关系

java缓冲区总结笔记

Buffer类(缓冲区族的基类,抽象类)

boolean isReadOnly():是否是只读缓冲区。只读缓冲区的内容不可更改,但是limit,position和mark值可以更改。

boolean isDirect():是否是直接缓冲区。直接缓冲区的IO速度快,但是申请和归还缓冲区的开销大。

int capacity():返回容量值。

int limit():返回极限值。

Buffer limit(int newLimit):设置极限值为newLimit,并返回本缓冲区。如果position大于newLimit,则会被设为newLimit;如果mark大于newLimit,则会被丢弃。

int position():返回position值。

Buffer position(int newPosition):设置当前位置为newPosition,并返回本缓冲区。如果mark大于newPosition,则会被丢弃。

int remaining():等于limit-position.

boolean hasRemaining():position不等于limit时返回true.

Buffer mark():在当前位置做标记,并返回本缓冲区。

Buffer reset():将position置为标记值,并返回本缓冲区。下次读写时就会从标记位置开始。

Buffer clear():将limit设置为capacity,将position设置为0,丢弃标记,返回本缓冲区。

Buffer flip():将limit设置为position,然后将position设置为0,丢弃标记,返回本缓冲区。通常用于写完缓冲区后为把缓冲区内的数据拷贝到别处做准备。

Buffer rewind():将position设置为0,丢弃标记,返回本缓冲区。

注意到上面的很多成员函数都返回调用它的对象,这种情况以前也出现了好几次,这主要是为了形成调用链,例如b.putInt(0xCAFEBABE).putShort(3).putShort(45);

ByteBuffer类(实现类)

申请字节缓冲区要采用ByteBuffer类的静态工厂方法。

ByteBuffer allocate(int capacity):申请一个容量为capacity的非直接字节缓冲区,其limit等于capacity,position为0,mark为不确定。

ByteBuffer allocateDirect(int capacity):同上,只不过申请的是直接字节缓冲区。

ByteBuffer wrap(byte[] array, int off, int len):将array本体的一部分当成缓冲区,缓冲区的capacity等于len,limit等于capacity,position为0,mark为不确定。修改array也就是修改缓冲区内容,修改缓冲区内容也就是修改array.

ByteBuffer warp(byte[] array):将array本体当成缓冲区。

ByteBuffer slice():为缓冲区现在的[position,limit-1]部分创建视图缓冲区,其capacity等于本体的limit-position,limit等于capacity,position为0,mark为不确定。视图缓冲区的概念和数据库中的视图一样,就是一个观察窗口。视图中做的更改会反映到本体上,本体上做的更改会反映到视图上,视图是只读缓冲区当且仅当本体是只读缓冲区,视图是直接缓冲区当且仅当本体是直接缓冲区。但是本体和视图的limit,position,mark值是相互独立的。

ByteBuffer duplicate():为整个缓冲区创建视图缓冲区,其capacity,limit,position和mark值都和本体相同。

ByteBuffer asReadOnlyBuffer():同上,只是视图缓冲区是只读的。

byte get():读position处的字节,然后position加1.

byte get(int index):读index位置的字节。

ByteBuffer get(byte[] dst, int off, int len):从position开始批量get数据到dst数组从off开始的位置,然后position加len,返回本缓冲区。

ByteBuffer get(byte[] dst):参照上面的。

ByteBuffer put(byte b):将position处写入b,然后position加1,返回本缓冲区。

ByteBuffer put(int index, byte b):在index处写入b,返回本缓冲区。

ByteBuffer put(byte[] src, int off, int len):把src数组从off开始的len个数据put到缓冲区从position开始的地方,然后position加len,返回本缓冲区。

ByteBuffer put(byte[] src):参照上面的。

ByteBuffer put(ByteBuffer src):将源缓冲区src剩下的n=src.remaining()个字节拷贝到本缓冲区的position开始的位置,两个缓冲区的position都加n,返回本缓冲区。注意src不能是本缓冲区。

ByteBuffer compact():将缓冲区中剩下的n=remaining()个字节移到从0开始的地方,并把limit设为capacity,position设为n,mark丢弃,返回本缓冲区。

ByteOrder order():获取本缓冲区的字节顺序是小尾(ByteOrder.LITTLE_ENDIAN)还是大尾(ByteOrder.BIG_ENDIAN)。

ByteBuffer order(ByteOrder bo):设置本缓冲区的字节顺序为小尾或大尾,返回本缓冲区。

【从下面开始,代号XXX=Char,Short,Int,Long,Float,Double】

XXX getXXX():读position处的XXX,然后position加XXX类型所占的字节数。

XXX getXXX(int index):读index(单位是字节)处的XXX。

ByteBuffer putXXX(XXX v):在position处写入v,然后position加XXX类型所占的字节数,返回本缓冲区。

ByteBuffer putXXX(int index, XXX v):在index(单位是字节)处写入v,返回本缓冲区。

XXXBuffer asXXXBuffer():类似于slice,也是为缓冲区的[position,limit-1]部分创建视图缓冲区,只是缓冲区按照几个字节一组变成了XXX型缓冲区,缓冲区的limit等于capacity,position为0,mark为不确定。视图缓冲区为只读的当且仅当本体是只读的,视图缓冲区是直接的当且仅当本体是直接的。

boolean equals(Object obj):如果本缓冲区与obj,元素类型相同,具有相同数量的剩余元素,且两个剩余元素序列逐点相同,则返回true.

int compareTo(ByteBuffer that):按照字典顺序比较本缓冲区和that的剩余元素序列,当本缓冲区小于、等于、大于that时,返回负整数、0、正整数。

String toString():返回汇总了缓冲区状态的字符串。

XXXBuffer类(实现类)

申请缓冲区也要采用XXXBuffer类的静态工厂方法。

XXXBuffer allocate(int capacity),XXXBuffer wrap(XXX[] array, int off, int len),XXXBuffer wrap(XXX[] array),XXXBuffer slice(),XXXBuffer duplicate(),XXXBuffer asReadOnlyBuffer(),XXX get(),XXX get(int index),XXXBuffer get(XXX[] dst, int off, int len),XXXBuffer get(XXX[] dst),XXXBuffer put(XXX v),XXXBuffer put(int index, XXX v),XXXBuffer put(XXX[] src, int off, int len),XXXBuffer put(XXX[] src),XXXBuffer compact(),boolean equals(Object obj),int compareTo(XXXBuffer that):参照ByteBuffer类的相应函数,只不过capacity,limit,position,mark等的单位都变成了XXX.

CharBuffer类补充

CharBuffer类除了XXXBuffer都有的那些函数之外,还有一些自己独有的函数。

CharBuffer wrap(CharSequence csq, int start, int end):将csq[start,end)本体当作字符缓冲区。

CharBuffer wrap(CharSequence csq):将csq本体当作字符缓冲区。

char charAt(int relativeIndex):返回(position+relativeIndex)处的字符。

int read(CharBuffer dst):将本缓冲区[position,limit-1]部分内的字符写入dst,返回实际写入的字符个数,如果position已经等于limit了则返回-1.

CharBuffer put(String src):在position处写入字符串src,然后position加src.length(),返回本缓冲区。

CharBuffer put(String src, int start, int end):在position处写入src[start,end),然后position加(end-start),返回本缓冲区。

CharBuffer append(char c):和CharBuffer put(char c)完全一样。

CharBuffer append(CharSequence csq):在position处写入字符序列csq,然后position加csq的长度,返回本缓冲区。

CharBuffer append(CharSequence csq, int start, int end):在position处写入字符序列csq[start,end),然后position加(end-start),返回本缓冲区。

String toString():返回缓冲区[position,limit-1]部分所组成的字符串,但是不会改变position值。

int length():返回缓冲区[position,limit-1]部分所包含的字符数。等价于int remaining()?

对缓冲区编码和解码

Charset类(字符集类)提供了编码ByteBuffer和解码CharBuffer的方法。

ByteBuffer encode(String str),ByteBuffer encode(CharBuffer cb):用本字符集编码。

CharBuffer decode(ByteBuffer bb):用本字符集解码。

创建Charset对象要使用Charset类的静态工厂方法:Charset forName(String charsetName).

取得平台默认的字符集使用Charset类的静态方法:Charset defaultCharset().