缓冲区基础

一个Buffer 对象是固定数量的数据的容器。其作用是一个存储器,或者分段运输区,在这里数据可被存储并在之后用于检索。对于每个非布尔原始数据类型都有一个缓冲区类。尽管缓冲区作用于它们存储的原始数据类型,但缓冲区十分倾向于处理字节。非字节缓冲区可以在后台执行从字节或到字节的转换,这取决于缓冲区是如何创建的。

下面就是buffer的类结构图:

[img]http://dl.iteye.com/upload/attachment/0078/1049/f2c8f701-4c2d-345a-a396-7b6973894f4c.png[/img]

1. 让我们来看看buffer的属性:
容量(Capacity)
缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能
被改变。
上界(Limit)
缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
位置(Position )
下一个要被读或写的元素的索引。位置会自动由相应的 get( ) 和put( )方法更新。
标记(Mark )
一个备忘位置。调用 mark( ) 来设定 mark = postion。调用 reset( ) 设定 position =
mark。标记在设定前是未定义的(undefined)。
这四个属性之间总是遵循以下关系:
0 <= mark <= position <= limit <= capacity


2. buffer中的API:
public abstract class Buffer {  
//返回缓冲器的长度
public final int capacity( )
//返回我们已经put的内容的长度,比如我们在0.1.2上面放了三个字节的内容,那 position的值就为3
public final int position( )
//把position指针放在指定的那个位置
public final Buffer position (int newPosition)
public final int limit( )
//设置缓冲器的上限值
public final Buffer limit (int newLimit)
public final Buffer mark( )
//将position返回到一个先前设定的标记。如果标记值未定义,调用reset() 将导致InvalidMarkException 异常
public final Buffer reset( )
//Clear()方法将缓冲区重置为空状态。它并不改变缓冲区中的任何数据元素,而是仅仅将上界设为容量的值,并把位置设回0
public final Buffer clear( )
public final Buffer flip( )
public final Buffer rewind( )
//remaining()方法将告知您从当前位置到上界还剩余的元素数目
public final int remaining( )
//判断是否已经达到了缓冲区的临界值(limit)
public final boolean hasRemaining( )
public abstract boolean isReadOnly( );
}



细心的人可以看到buffer中为甚没有put和get方法因为每个他的子类都会有这两个方法。但它们所采用的参数类型,以及它们返回的数据类型,对每个子类来说都是唯一的,所以它们不能在顶层 Buffer 类中被抽象地声明。比如byteBuffer(其他类都是一样的,只是返回参数不容)我就可以看到这两个方法,如下:
public abstract class ByteBuffer
extends Buffer implements Comparable
{
public abstract byte get( );
public abstract byte get (int index);
//在position指针处放置b,position值加1
public abstract ByteBuffer put (byte b);
//在指定的位置放置b,但是不会改变position的值
public abstract ByteBuffer put (int index, byte b);
}

3. [b]翻转:[/b] 当我们已经写满了缓冲区,现在我们必须准备将其清空。[b]我们想把这个缓冲区传递给一个通道,以使内容能被全部写出。并且把position设置为起始位置。[/b]
我们可以使用[b]flip()[/b]方法。下面就是调用flip方法前后的变化:
调用之前:postion的值为6,limit的值为10

[img]http://dl.iteye.com/upload/attachment/0078/1066/b310328b-8712-3eda-a992-4395c51b9503.png[/img]

调用之后:postion的值为0,limit的值变为原来的position的值(6)

[img]http://dl.iteye.com/upload/attachment/0078/1068/7d00cf60-e92b-3813-bc68-14dbd22b222c.png[/img]


4.比较两个缓冲器:
两个缓冲区被认为相等的充要条件是:
1、两个对象类型相同。包含不同数据类型的 buffer 永远不会相等,而且 buffer
绝不会等于非 buffer 对象。
2、两个对象都剩余同样数量的元素。Buffer 的容量不需要相同,而且缓冲区中剩
余数据的索引也不必相同。[b]但每个缓冲区中剩余元素的数目(从位置到上界)必须相
同。 [/b]
3、在每个缓冲区中应被 Get() 方法返回的剩余数据元素序列必须一致。

[img]http://dl.iteye.com/upload/attachment/0078/1077/528501ca-7a8c-3bc3-8f8c-f401598d5fc4.png[/img]


5.批量移动
缓冲区的涉及目的就是为了能够高效传输数据。一次移动一个数据元素,如例2-1 所示的那样并不高效。如您在下面的程序清单中所看到的那样,buffer API 提供了向缓冲区内外批量移动数据元素的方法。
public abstract class CharBuffer  
extends Buffer implements CharSequence, Comparable
{
// This is a partial API listing

public CharBuffer get (char [] dst)
public CharBuffer get (char [] dst, int offset, int length)

public final CharBuffer put (char[] src)
public CharBuffer put (char [] src, int offset, int length)
public CharBuffer put (CharBuffer src)

public final CharBuffer put (String src)
public CharBuffer put (String src, int start, int end)
}


get() 是供从缓冲区到数组进行的数据复制使用, 调用 get() 会向前移动缓冲区的位置属性
Put() 的批量版本工作方式与get相似,但以相反的方向移动数据,从数组移动到缓冲区


6.创建缓冲区
public abstract class CharBuffer  
extends Buffer implements CharSequence, Comparable
{
// This is a partial API listing

public static CharBuffer allocate (int capacity)

//创建一个用自己数组(array)的缓冲区
public static CharBuffer wrap (char [] array)
public static CharBuffer wrap (char [] array, int offset,
int length)

//告诉您这个缓冲区是否有一个[b]可存取[/b]的备份数组
public final boolean hasArray( )
public final char [] array( )
//返回缓冲区数据在数组中存储的开始位置的偏移量(从数组头 0 开始计算)。
public final int arrayOffset( )
}


要分配一个容量为 100 个char 变量的 Charbuffer:
CharBuffer charBuffer = CharBuffer.allocate (100);
其实,这段代码隐含地从堆空间中分配了一个 char 型数组作为备份存储器来储存 100 char变量。
如果您想提供您自己的数组用做缓冲区的备份存储器,请调用 wrap()方法:
char [] myArray = new char [100];
CharBuffer charbuffer = CharBuffer.wrap (myArray);
创建了一个position 值为12,limit 值为54,容量为myArray.length 的缓冲区。
CharBuffer charbuffer = CharBuffer.wrap (myArray, 12, 42);


6. 复制缓冲区
public abstract class CharBuffer
extends Buffer implements CharSequence, Comparable
{
// This is a partial API listing

//两个缓冲区[b]共享数据元素[/b],拥有同样的容量,但每个缓冲区拥有各自的位置,上界和标记属性。
public abstract CharBuffer duplicate( );
//生成一个只读的缓冲区视图。其他都与duplicate()相同
public abstract CharBuffer asReadOnlyBuffer( );
//创建一个从原始缓冲区的当前位置开始的新缓冲区,并且其容量是原始缓冲区的剩余元素数量(limit - position )。这个新缓冲区与原始缓冲区共享一段数据元素子序列。
public abstract CharBuffer slice( );
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值