您的位置:首页 > 职场人生

黑马程序员_字节流缓冲区入门讲解

2013-08-15 11:14 309 查看

字节流缓冲区原理讲解

自定义字节流缓冲区,原理:先利用FileInputStream的read方法从硬盘中一个个的读取数据存入到内存中定义的数组中,然后在利用BufferedInputStream的read方法从字节数组中一个一个的往外读.

为什么在BufferedReader 中模拟缓冲区用Buffered,而这里用字节数组。看下面代码:
public  class MyBufferedStream extends InputStream {

private InputStream f;
private byte[] by=new byte[1024];
private int count=0,pos=0;
public MyBufferedStream(InputStream f){
this.f=f;
}
public int myRead()throws IOException {/*这个地方为什么要用int来接收。如果按照Byte来接收,就有可能会出现连续读到8个1也就是-1
,这时候就与结束符-1矛盾,就会出现不能够读完整,把接接收类型改为int类型后,8个一位的-1就变成了32位,并在提升的过程我们&上了255(8个1)
,这样即能够保证最低8为数据的原样,避免了伪结束-1.
*/
if(count==0){
count=f.read(by);
if(count<0)
return -1;
pos=0;
byte b=by[pos];
pos++;
count--;
return b&255;//为什么需要与上255。(返回类型为Int)
}
else if(count>0){
byte b=by[pos];
pos++;
count--;
return b&0XFF;
}
return -1;
}
public void myClose()throws IOException{//向外提供一个关闭流的方法。
f.close();
}

@Override
public int read() throws IOException {
// TODO Auto-generated method stub
return 0;
}
}
class DemoBuffered
{
public static void main(String[] args)throws IOException{
FileInputStream fr=new FileInputStream("SystemIO\\copy1.mp3");
MyBufferedStream mbs=new MyBufferedStream(fr);
FileOutputStream fos=new FileOutputStream("SystemIO\\copy3.mp3");
int b=0;
long start=System.currentTimeMillis();
while(( b=mbs.myRead())!=-1){
fos.write(b);
}
mbs.myClose();
fos.close();
long end=System.currentTimeMillis();
System.out.println(end-start);
}
}


根据代码输入结果详细讲述:
一个int是4个8位,byte是一个8位。
11111111-111111110000000000101001001010100101010010101001010

byte: -1 ---> int : -1;

00000000 00000000 00000000 11111111 255

11111111 11111111 11111111 11111111

11111111 -->提升了一个int类型 那不还是-1吗?是-1的原因是因为在8个1前面补的是1导致的。

那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。

怎么补0呢?

11111111 11111111 11111111 11111111

&00000000 00000000 00000000 11111111

------------------------------------

00000000 00000000 00000000 11111111

0000-0001

1111-1110

000000001

1111-1111 -1

结论:

字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。

因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.

那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。

所以,为了避免这种情况将读到的字节进行int类型的提升。

并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。

而在写入数据时,只写该int类型数据的最低8位。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐