自緩衝輸入流,用於構建流媒體
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;
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.