自缓冲输入流,用于构建流媒体

 package com.willfar.commons.cloud;

import java.io.IOException;  
import java.io.InputStream;  
  
/** 
 * 自缓冲输入流,用于构建流媒体 
 * @author redduke 
 * @since 0.6 
 */  
public class SelfBufferedInputStream extends InputStream  
{  
    /* 
     * 输入流 
     */  
    protected InputStream in;  
    /* 
     * 缓冲 
     */  
    protected byte[] buf;  
    /* 
     * 可读取字节数 
     */  
    protected int size=0;  
    /* 
     * 缓冲池当前可读位置 
     */  
    protected int pos=0;  
      
    /* 
     * 流结束 
     */  
    protected boolean closed=false;  
      
    /* 
     * 自动缓冲比例 
     */  
    protected int autoBufferScale=100;  
    /** 
     * 构造方法 
     * 缺省缓冲池大小为2048,缺省自动缓冲比例为100 
     */  
    public SelfBufferedInputStream(InputStream in) {  
        this(in,2048,100);  
    }  
    /** 
     * 构造方法,指定缓冲池大小,缺省自动缓冲比例为100 
     */  
    public SelfBufferedInputStream(InputStream in,int bufferSize)  
    {  
        this(in,bufferSize,100);  
    }  
    /** 
     * 构造方法,指定缓冲池大小和自动缓冲比例 
     */  
    public SelfBufferedInputStream(InputStream in,int bufferSize,int autoBufferScale)  
    {  
        this.in=in;  
        createBuffer(bufferSize);  
        setAutoBufferScale(autoBufferScale);  
        startBuffer();        
    }  
    /* 
     * 创建缓冲数组 
     */  
    private void createBuffer(int bufferSize)  
    {  
        if(bufferSize<2048)  
            bufferSize=2048;  
        buf=new byte[bufferSize];  
    }  
    /** 
     * 读取单个字节 
     * @see java.io.InputStream#read(); 
     */  
    public int read() throws IOException {  
        //结束  
        if(closed && size<1)  
            return -1;  
        //低于缓冲阙值,开始缓冲  
        if(!closed && !this.buffering && this.getBufferScale()<this.autoBufferScale)  
            this.startBuffer();  
        //等待缓冲        
        while(size<1)  
        {  
            if(size<1 && closed)  
                return -1;  
            try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
        }  
        //从缓冲中读取  
        size--;  
        int ret=this.buf[pos++]&0xff;  
        pos%=buf.length;  
        return ret;  
    }  
    /** 
     * 返回可读字节数 
     * @see java.io.InputStream#available() 
     */  
    public int available() throws IOException {  
        return in.available()+size;  
    }  
    /** 
     * 关闭此流 
     * @see java.io.InputStream#close() 
     */  
    public void close() throws IOException {  
  
        this.closed=true;  
        in.close();  
    }  
    /** 
     * @see java.io.InputStream#mark(int) 
     */  
    public synchronized void mark(int readlimit) {  
    }  
    /** 
     * 测试是否支持mark,此类不支持mark 
     */  
    public boolean markSupported() {  
        return false;  
    }  
    /** 
     * @see java.io.InputStream#read(byte[], int, int) 
     */  
    public int read(byte[] b, int off, int len) throws IOException {  
        int read=0;  
        int ch;  
        for(int i=0;i<len;i++)  
            if((ch=read())!=-1)  
            {  
                b[off+i]=(byte)ch;  
                read++;  
            }  
            else  
                return read;  
        return len;  
    }  
    /** 
     * @see java.io.InputStream#read(byte[]) 
     */  
    public int read(byte[] b) throws IOException {  
        int read=0;  
        int ch;  
        for(int i=0;i<b.length;i++)  
            if((ch=read())!=-1)  
            {  
                b[i]=(byte)ch;  
                read++;  
            }  
            else  
                return read;  
        return b.length;  
    }  
    /** 
     * @see java.io.InputStream#read() 
     */  
    public synchronized void reset() throws IOException {  
    }  
    /** 
     * 从输入流跳过n个字节 
     * @see java.io.InputStream#skip(long) 
     */  
    public long skip(long n) throws IOException {  
        if(n<=0)  
            return 0;  
        for(long i=0;i<n;i++)  
            if(read()==-1)  
                return i+1;  
        return n;  
    }  
    /* 
     * 正在缓冲的标记 
     */  
    private boolean buffering=false;  
    /** 
     * 测试是否正在缓冲 
     */  
    public boolean isBuffering()  
    {  
        return buffering;  
    }  
    /* 
     * 开始缓冲 
     */  
    protected void startBuffer()  
    {  
        if(buffering || closed)  
            return;  
        buffering=true;  
        new Thread(){  
            public void run(){  
                buffer();                 
            }}.start();  
    }  
    /* 
     * 缓冲  
     */  
    protected void buffer()  
    {  
        while(size<this.buf.length)  
        {  
            int ch=-1;  
            try  
            {  
                ch=in.read();  
            }  
            catch(IOException ex){  
                this.closed=true;  
                break;  
            }  
              
            if(ch==-1)  
            {  
                this.closed=true;  
                break;  
            }  
            else  
            {  
                this.buf[(pos+size)%buf.length]=(byte)ch;  
                size++;  
            }  
        }  
        buffering=false;  
    }  
    /** 
     * 获取缓冲池缓冲百分比,如果源数据流已经关闭,则总是返回100 
     */  
    public int getBufferScale()  
    {  
        if(this.closed)  
            return 100;  
        return this.size*100/buf.length;  
    }  
    /** 
     * 设置开始自动缓冲的比例 
     * @param scale 如果缓冲池的比例小于scale,则自动缓冲,1~100 
     */  
    public void setAutoBufferScale(int scale)
    {  
        if(scale<1 || scale>100)  
            scale=100;  
        this.autoBufferScale=scale;  
    }  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值