自緩衝輸入流,用於構建流媒體

 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;  
    }  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章