BufferedInputStream.java

package textconvert;

import java.io.IOException;
import java.io.InputStream;

/**
 * peek or unread: the count should be less than half of the buffer size.
 * @author Bing
 *
 */
public class BufferedInputStream extends InputStream{
    private InputStream inStream;
    protected byte[] buffer = null;
    private int buffer_index = 0;
    private int buffer_size = 0;
    private int markpos;
    private ConstByteArray byteArray = null;
    private boolean byteArrayLocked = false;
    private boolean isInStreamEOF = false;

    public BufferedInputStream(InputStream inStream){
        this(inStream, 8192);
    }
    /**
     * struct with buffer size, default 8192 (8K)
     * @param inStream
     * @param size
     */
    public BufferedInputStream(InputStream inStream, int size){
        this.inStream = inStream;
        if(size % 2 != 0){
            size ++;
        }
        this.buffer = new byte[size];
        this.byteArray = new ConstByteArray(this.buffer, 0, size);
    }

    public final int read() throws IOException{
        if(buffer_index>=buffer_size){           
            if(buffer_getNext()==-1)
                return -1;
        }
        return buffer[buffer_index++] & 0xff;   
    }
    /**
     * find a byte and lock the whole buffer
     * @param b
     * @param maxCount  should be less than half of buffer size
     * @return
     * @throws IOException
     */
    public final ConstByteArray findBytePeekLock(byte b, int maxCount) throws IOException{
        byteBufferPeekLock(maxCount);
        byteBufferUnlock(0);
        int i;
        for(i=this.buffer_index; i<this.buffer_size; i++){
            if(buffer[i] == b){
                break;
            }
        }
        if(i == this.buffer_size)
            return null;
        return byteBufferPeekLock(i - this.buffer_index);
    }
    /**
     * peek bytes(size) and lock the whole buffer
     * @param size
     * @return
     * @throws IOException
     */
    public final ConstByteArray byteBufferPeekLock(int size) throws IOException{
        if(size > this.buffer.length/2)
            throw new IOException("error:size > buffer.length/2");

        if(!this.isInStreamEOF && buffer_size - buffer_index -1 <size){
            this.moveBufferAndFill();
        }   
        int len = Math.min(size, buffer_size - buffer_index -1);
        this.byteArray.resetSize(this.buffer_index,len);
        byteArrayLocked = true;
        return this.byteArray;
    }
    /**
     * unlock and skip bytes
     * @param skipByteCount
     * @throws IOException
     */
    public final void byteBufferUnlock(int skipByteCount) throws IOException{
        byteArrayLocked = false;
        this.skip(skipByteCount);
    }

    public void mark(int readlimit){
        if(readlimit>buffer.length/2)
            return;
        try {
            if(buffer_index>buffer.length/2 && readlimit > buffer_size - buffer_index - 1){               
                moveBufferAndFill();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        markpos = buffer_index;
    }

    public boolean markSupported() {
        return true;
    }

    public void reset(){
        buffer_index = markpos;
    }


    public void close(){
        buffer = null;
    }
    /**
     * buffer size
     * @return
     */
    public final int getBufferSize(){
        return this.buffer.length;
    }

    /**
     *
     * @param bytes
     * @param peekLength
     * @return offset from the current position
     * @deprecated
     */
    public int matchBytesPeek(byte[] bytes, int peekLength) throws IOException{       
        int halfCap = buffer.length /2;
        if(bytes.length >  halfCap)
            return -1;
        if(buffer_index >= halfCap &&
                buffer_size - buffer_index -1 < bytes.length){
            if(moveBufferAndFill()==-1)
                return -1;
                }
        int maxIndex = buffer_index + peekLength;
        for(int i=buffer_index; i<maxIndex; i++){
            int j;
            for( j=0; j<bytes.length; j++){
                if(buffer[i + j] != bytes[j]){
                    break;
                }
            }
            if(j==bytes.length)
                return i;
        }
        return -1;
    }

    public void skip(int n) throws IOException{
        if(n <= buffer_size - buffer_index)   
            buffer_index += n;
        else{
            super.skip(n);
            buffer_size = 0;
            buffer_index = 0;
        }
    }
    /**
     * move buffer to previous buffer and read new to fill the rest
     * @return the newly read bytes
     * @throws IOException
     */
    private int moveBufferAndFill() throws IOException{
        if(this.byteArrayLocked)
            throw new IOException("buffer locked!");
        int len = -1;
        if(buffer_index >= buffer.length /2){
            try {
                System.arraycopy(buffer, buffer_index, buffer, 0, buffer_size - buffer_index - 1);
                len = this.inStream.read(buffer, buffer_size, buffer.length-buffer_size);
                if(len!=-1)
                    buffer_size += len;
                else
                    this.isInStreamEOF = true;
                buffer_index = 0;               
            } catch (IOException e) {
                e.printStackTrace();
            }           
        }   
        return len;
    }
    /**
     * clear buffer and read new bytes
     * @return the newly read bytes count
     * @throws IOException
     */
    private int buffer_getNext() throws IOException{
        if(this.byteArrayLocked)
            throw new IOException("buffer locked!");
        int len = -1;
        try{
            len = this.inStream.read(buffer, 0, buffer.length);
            if(len != -1)
                buffer_size = len;
            else
                this.isInStreamEOF = true;
            buffer_index = 0;
        }catch(Exception e){
            e.printStackTrace();
        }
        return len;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值