写一个字节流缓冲区的装饰类,类似于BufferedInputStream。
思路;1、定义数组:开辟缓冲区,将所抓取的数据放置在缓冲区内
2、定义指针:指示每次要从缓冲区中读取的数据
3、定义计数器:记录缓冲区中的有效数据;当计数器指到0的时候,再重新抓一批数据放进缓冲区中
代码:
import java.io.*;
public class MyBufferedInputStream
{
private InputStream r;
public MyBufferedInputStream(InputStream r)
{
this.r=r; //1、传进来待提高效率的读字节流对象
}
private byte[] b=new byte[1024]; //2、定义一个缓冲区,大小可以定义为1024字节
private int count=0,pos=0; //3、count指示还剩多少字节数据(计数器);pos指示应当取出哪个字节的数据
public int MyRead() throws IOException
{
if(count==0) //如果count为0,表示已经取完缓冲区中1024个数据,应当再取1024个数据
{
count=r.read(b); //count记录取出了多少数据
if (count==-1) //如果count==1,则表示已经到达目标文件末尾,返回-1;
return -1;
pos=0; //否则将pos定义为0,取出1024个数据中第一个数据!
count--; //count自减1,表示取出一个数据
return b[pos++]&255;
}
else if(count>0) //如果count>0,表示之前存入的1024个数据还没取完,应当继续取那1024个数据
{
count--;
return b[pos++]&255;
}
else
return -1;
}
public void MyClose() throws IOException
{
r.close();
}
}
注意:
1、在MyRead代码中,返回的是b[pos],其类型为byte,但是方法返回类型是int类型的,byte类型占一个字节,但是int类型占4个字节,这样就等于把原有1个字节提升为4个字节,而且补上的是3个字节的1111 1111,由原码补码可知,当原始byte数据为1111 1111时,再加上3个字节的1111 1111,其原码实质为-1,由于返回的是-1,则程序以为读到了末尾,造成这种现象的就是因为byte转换为int后,加了三个字节的1111 1111,更改了原始byte数据。解决办法就是只要最后一个字节有效,则将提升后的int数据与255进行与操作,即将前三个字节强制变为0000 0000,这样就保证了原始byte数据,因此返回时用了:
return b[pos++]&255;
2、那在write方法中,则与read方法执行了一个恰好相反的操作,对比read方法在进行补0提升的过程,write方法则将int类型强制转换为byte类型,且只取最低8位!
int len=0;
while((len=fr.read())!=-1)
fw.write(len); //将len转化为byte类型,只保留最低8位!