用java实现动态buffer

动态buffer,通过头部指针以及有效长度来定义buffer的有效数据区,可循环使用整个buffer区域。支持自动增加buffer大小,从buffer中读取数据,往buffer写数据。修改buffer指定位置指定长度的数据。

1、动态增加buffer大小。

重新分配一个byte数组,长度满足当前需求,将之前byte数组的内容copy至新byte数组。重置buffer的头部指针,大小,有效长度等值。

/**
     * realloc buffer ,new size equals with old size plus len
     * @param len
     */
    public void reAlloc(int len){
    	byte[] tmp=new byte[size+len];
    	if(validLen>0){
    		byte[] tmp1=read(validLen);
	    	for(int i=0;i<tmp1.length;i++){
	    		tmp[i]=tmp1[i];
	    	}
	    	this.validLen=tmp1.length;
    	}
    	this.buf=tmp;
    	this.head=0;
    	this.size+=len;
    }

2、从buffer指定位置读取指定长度数据

/**
	 * read data ,not move the head nor the validLen
	 * @param len
	 * @return
	 */
	public byte[] read(int offset,int len){
		if(len<=0 || validLen<=0){
			return null;
		}
		if(len>validLen){
			return null;
		}
		byte[] readBuf=new byte[len];
		if(head+offset+len<=size){
			for(int i=0;i<len;i++){
				readBuf[i]=buf[head+offset+i];
			}
		}else if(head+offset+len>size){
			//first read from head to size,total read bytes is size-head
			for(int i=0;i<size-head-offset;i++){
				readBuf[i]=buf[head+offset+i];
			}
			//then read from the beginning of the buffer,read bytes is len+head-size
			for(int i=0;i<len+head+offset-size;i++){
				readBuf[size-head-offset+i]=buf[i];
			}
		}
		return readBuf;
	}

3、往buffer写数据

/**
	 * append data to buffer,increase validLen
	 * @param src
	 * @param len
	 */
    public void append(byte[] src,int len){
    	if(getAvailabeSize()<len){
    		reAlloc(len);
    	}
    	
    	if(head+validLen+len<=size){
    		for(int i=0;i<len;i++){
        		buf[head+validLen+i]=src[i];
        	}
    	}else if(head+validLen+len>size){
    		if(head+validLen>=size){
    			for(int i=0;i<len;i++){
            		buf[head+validLen-size+i]=src[i];
            	}
        	}else if(head+validLen<size){
        		//first append from head+validLen to size
    			for(int i=0;i<size-head-validLen;i++){
    				buf[head+validLen+i]=src[i];
    			}
    			//then append from the beginning of the buffer
    			for(int i=0;i<len+head+validLen-size;i++){
    				buf[i]=src[size-head-validLen+i];
    			}
    		}
    	}
    	validLen+=len;
    }

4、修改buffer的数据内容

public void modify(int offset,int len,byte[] src){
    	for(int i=0;i<len;i++){
    		buf[offset+i]=src[i];
    	}
    }

5、完整代码片

package com.klaus.utils;

public class Buffer {
    private int size;
    private byte[] buf=null;
    public int validLen=0;
    public int head=0;
    public boolean isCompleted = false;
	public Buffer(int size){
		this.size=size;
		this.buf=new byte[size];
		this.head=this.validLen=0;
	}
	public Buffer(byte[] buf,int len){
		this.buf=new byte[len];
		for(int i=0;i<len;i++){
			this.buf[i]=buf[i];
		}
		this.validLen=len;
		this.head=0;
		this.size=len;
	}
	public void init(){
		head=0;
		validLen=0;
		isCompleted = false;
	}
	/**
	 * read data ,not move the head nor the validLen
	 * @param len
	 * @return
	 */
	public byte[] read(int len){
		if(len<=0 || validLen<=0){
			return null;
		}
		if(len>validLen){
			return null;
		}
		byte[] readBuf=new byte[len];
		if(head+len<=size){
			for(int i=0;i<len;i++){
				readBuf[i]=buf[head+i];
			}
		}else if(head+len>size){
			//first read from head to size,total read bytes is size-head
			for(int i=0;i<size-head;i++){
				readBuf[i]=buf[head+i];
			}
			//then read from the beginning of the buffer,read bytes is len+head-size
			for(int i=0;i<len+head-size;i++){
				readBuf[size-head+i]=buf[i];
			}
		}
		return readBuf;
	}
	/**
	 * read data ,not move the head nor the validLen
	 * @param len
	 * @return
	 */
	public byte[] read(int offset,int len){
		if(len<=0 || validLen<=0){
			return null;
		}
		if(len>validLen){
			return null;
		}
		byte[] readBuf=new byte[len];
		if(head+offset+len<=size){
			for(int i=0;i<len;i++){
				readBuf[i]=buf[head+offset+i];
			}
		}else if(head+offset+len>size){
			//first read from head to size,total read bytes is size-head
			for(int i=0;i<size-head-offset;i++){
				readBuf[i]=buf[head+offset+i];
			}
			//then read from the beginning of the buffer,read bytes is len+head-size
			for(int i=0;i<len+head+offset-size;i++){
				readBuf[size-head-offset+i]=buf[i];
			}
		}
		return readBuf;
	}
	/**
	 * read data ,and move the head ,decrease the validLen
	 * @param len
	 * @return
	 */
	public byte[] readAndMove(int len){
		byte[] read = read(len);
		//move head to new location,decrease validLen
		validLen-=len;
		if(head+len<=size){
			head+=len;
			if(head==size){
				head=0;
			}
		}else{
			head=(len+head-size);
		}
		return read;
	}
	/**
	 * append data to buffer,increase validLen
	 * @param src
	 * @param len
	 */
    public void append(byte[] src,int len){
    	if(getAvailabeSize()<len){
    		reAlloc(len);
    	}
    	
    	if(head+validLen+len<=size){
    		for(int i=0;i<len;i++){
        		buf[head+validLen+i]=src[i];
        	}
    	}else if(head+validLen+len>size){
    		if(head+validLen>=size){
    			for(int i=0;i<len;i++){
            		buf[head+validLen-size+i]=src[i];
            	}
        	}else if(head+validLen<size){
        		//first append from head+validLen to size
    			for(int i=0;i<size-head-validLen;i++){
    				buf[head+validLen+i]=src[i];
    			}
    			//then append from the beginning of the buffer
    			for(int i=0;i<len+head+validLen-size;i++){
    				buf[i]=src[size-head-validLen+i];
    			}
    		}
    	}
    	validLen+=len;
    }
    /**
     * realloc buffer ,new size equals with old size plus len
     * @param len
     */
    public void reAlloc(int len){
    	byte[] tmp=new byte[size+len];
    	if(validLen>0){
    		byte[] tmp1=read(validLen);
	    	for(int i=0;i<tmp1.length;i++){
	    		tmp[i]=tmp1[i];
	    	}
	    	this.validLen=tmp1.length;
    	}
    	this.buf=tmp;
    	this.head=0;
    	this.size+=len;
    }
    public void modify(int offset,int len,byte[] src){
    	for(int i=0;i<len;i++){
    		buf[offset+i]=src[i];
    	}
    }
    /**
     * get available buffer size,if not enough ,call reAlloc to add the buffer size dymaticly
     * @return
     */
    public int getAvailabeSize(){
    	return size-validLen;
    }
    public byte[] getBuffer(){
    	return buf;
    }
    public int getSize(){
    	return size;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值