FileInputStream的read方法是直接从系统中的磁盘中读取数据,较消耗资源。
缓冲区的作用就是通过包装类包装FileInputStream对象fis,通过fis的read方法存储到缓冲区的字节数组中,再调用缓冲区的加强read方法,循环遍历字节数组即可。解释:循环遍历字节数组比遍历磁盘中的数据要快得多。
import java.io.IOException; import java.io.InputStream; public class MyBufferedInputStream { private InputStream input=null; byte[] buf=new byte[1024*4]; int count=0,index=0; MyBufferedInputStream2(InputStream input){ this.input=input; } public int myRead() throws IOException{ if(count==0){ count=input.read(buf); if(count<0){ return -1; } index=0; } if(count>0){ byte b=buf[index]; count--; index++; return b*0xff; } return -1; } }
return b*0xff;
因为数据是由0101二进制的排列组合组成的。
所以有可能出现1111-1111八个1的情况,然而读一个字节,相当于读了一个八个2进制位。
但由于1111-1111的十进制是-1。
<span style="font-size:14px;">解释: 它的最高位是1,所以是负数. 按补码规则,如下等式成立: 负数 = 负数的绝对值按位取反+1 负数按位取反+1 =负数的绝对值 所以11111111按位取反+1 就等于 1. 因此,对应-1。</span>
这也就解释了为什么用的是byte数组却要返回int而不是byte的原因。
因为返回int的话,byte会自动提升,而不加&0xff的话,返回的int仍旧是-1。
解释为何要加&0xff:
为了避免byte的1111-1111转int变为1111-1111 1111-1111 1111-1111 1111-1111 结果还是-1。
就“与”一下。
1111-1111 1111-1111 1111-1111 1111-1111
& 0000-0000 0000-0000 0000-0000 1111-1111 -->255-->0xff
就能得到正确的值了。
2、
将byte进行int提升,会导致1个字节变为4个字节。
往外写的话按照int往外写,那应该是原来数据的4倍才对。
但事实为什么没有呢?
read方法在向上提升,它在往前面补0,保证不是-1这种情况的发生,而write方法,它其实在做一个强转动作。
write方法其实就是将最低8位写进去。剩下的全砍掉。
int在做提升,write在做强转,所以就能保证源数据的不变化。
原文地址:http://blog.csdn.net/duoduoluojia/article/details/46553273