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;
}
}