理解 java 缓冲区

1,buffer


缓冲区成员:

 private int mark = -1;//一个备忘位置,调用mark()方法时,mark = position;调用reset()方法时,position=mask;
 private int position = 0;//位置,下一个要被读取或写的元素的索引,位置会自动由相应的get(),put()函数更新。
 private int limit;//上界,缓冲区第一个不能被读取或写的元素。或者说缓冲区中现存元素的计数,或者代表有效数据的末端
 private int capacity;//容量,在缓冲区被创建时设定,且永远不能被改变
 long address;


buffer中遵循这样的关系:

0<= mark <= position <=limit <=capacity


填充:

现在将hello填充到buffer:

b.put((byte)'H').put((byte)'e').put((byte)'l').put((byte)'l').put((byte)'0');




修改:将原来的Hello,修改为Mellow

b.put(0,(byte)'M').put((byte)'w');

翻转:

我们已经写满了缓冲区,现在我们必须将其清空,我们想把这个缓冲区传递给一个通道,以使内容全部被写出,我们可以人工实现代码

b.limit(b.position()).position(0);
或者直接调用

b.flip();

flip()用于翻转缓冲区,翻转后的效果图为:翻转后的缓冲区无法写入,只能读取


下面代码是将数据元素从数据缓冲区释放到一个数组:

int count = buffer.hasRemaining();
for (int i = 0; i<count; i++) { 
	myByteArray [i] = buffer.get( ); 
}
值得注意的是:缓冲区不是线程安全的,在需要并发操作时,需要先同步

使用b.clear()可以将缓冲区重置为空状态

下面是一个练习缓冲区的例子

package com.asdc.webservice;

import java.nio.CharBuffer;
public class BufferFillDrain {
	private static int index = 0; 
	private static String [] strings = { 
	"A random string value", 
	"The product of an infinite number of monkeys", 
	"Hey hey we're the Monkees", 
	"Opening act for the Monkees: Jimi Hendrix", 
	"'Scuse me while I kiss this fly", // Sorry Jimi ;-) 
	"Help Me! Help Me!", 
	}; 
	
	public static void main(String[] args) {
		CharBuffer charBuffer = CharBuffer.allocate(100);
		//当判断为true,则可以翻转这个数组
		while(fillBuffer(charBuffer)){
			charBuffer.flip();//翻转缓冲区
			drainBuffer(charBuffer);
			charBuffer.clear();//清空缓冲区
		}
	}

	private static void drainBuffer(CharBuffer charBuffer) {
		char [] smallArr = new char[10];
		while(charBuffer.hasRemaining()){
			int len = Math.min(charBuffer.remaining(), smallArr.length);
			charBuffer.get(smallArr, 0, len);
		}
		System.out.println("");
		
	}

	private static boolean fillBuffer(CharBuffer charBuffer) {
		if(index>=strings.length){
			//不填充
			return false;
		}
		String string = strings[index++];
		
		while(charBuffer.remaining()>string.length()){
			
			charBuffer.put(string);//等价于charBuffer.put(string,0,string.length());
			
		}
		
		return true;
	}
}


压缩缓冲区:

buffer.compact()

调用compact()方法是丢弃已经释放掉的数据,保留未释放的数据,并使缓冲区对重新填充容量准备就绪

压缩前的缓冲区:

压缩后的缓冲区:


标记:使缓冲区能记住一个位置并在之后返回

调用mark()时,将当前位置作为标记

调用reset()时,返回到之前标记的地方

注意:1,rewind( ),clear( ),flip( )总是丢弃标记

    2,如果新设定的值小于当前的值,调用limit( )和position( )带有索引参数的版本会抛弃标记

执行下面代码后:设定标记为2

buffer.position(2).mark().position(4);

如果此时将缓冲区传递给管道,则“ow”将被发送,而且position会前进到6

如果此时调用reset( );则position后退到2,若此时将缓冲区传递给管道,这"llow"将被发送,而且position会前进到6

相等:

判断两个缓冲区相等的充要条件是:

1,两个对象类型相同

2,两个缓冲区剩余同样数量的元素

3,每个缓冲区被get( )函数返回的数据元素序列必须一致


//缓冲区复制
CharBuffer buffer = CharBuffer.allocate(10);
buffer.position(3).limit(6).mark().position(5);
CharBuffer duBuffer = buffer.duplicate();
buffer.clear();



//缓冲区分割
char [] myBuff = new char[100];
CharBuffer cb = CharBuffer.wrap(myBuff);
cb.position(12).limit(21);
CharBuffer sliceBuffer = cb.slice();









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值