- import java.io.IOException;
- import java.io.InputStream;
- /**
- * 自定义字节缓冲流 简单模拟实现BufferedInputStream中的read()方法
- * */
- public class MyBufferedInputStream {
- //持有一个InputStream对象实例
- private InputStream in;
- //定义一个字节数组,用于暂时缓存读取的数据
- private byte[] buf = new byte[1024*4];
- //定义一个指针
- int pos = 0;
- //定义计数器
- int count = 0;
- public MyBufferedInputStream(InputStream in){
- this.in = in;
- }
-
- //定义一个myRead()方法,简单模拟实现BufferedInputStream中的read()方法
- public int myRead() throws IOException{
- //如果计数器(字节数组的数据大小)为0,说明字节数组为空,没有数据,需要从硬盘上读取数据
- if(count == 0){
- count = in.read(buf);
- //如果硬盘上的数据已经全部读取完
- if(count < 0){
- return -1;
- }
- //每次从硬盘上重新读取数据存储到字节数组中后都将指针重置
- pos = 0;
- //获取字节数组中的第一个字节数据
- byte b = buf[pos];
- //计数器减一
- count--;
- //指针后移一位
- pos++;
- //返回数据
- return b&255; //此次详解见下面(1)
- }else if(count > 0){
- byte b = buf[pos];
- //计数器减一
- count--;
- //指针后移一位
- pos++;
- //返回数据
- return b&255; //此次详解见下面(1)
- }
- return -1;
- }
- //定义一个关闭流的方法,用于模拟BufferedInputStream中的close()方法
- public void close() throws IOException{
- in.close();
- }
- }
- /*(1):读取字节数组中的数据都是byte类型,而最后返回值类型却是int类型,是将byte类型数据自动转换成int类型,是为了避免读取到的一个字节类型,其八位都是1的情况,
- 1个byte类型的数据,其八位都是1,意味着该字节的值为-1,转换int类型后也是-1,就会因为返回值是-1而误认为文件数据已经读取完。
- byte b = buf[pos]; b是byte类型,占八位,如果1个字节八位都是1,即11111111,转换成int类型,即十进制就是-1
- 如:byte -1 --->二进制是 11111111
- int -1 -----> 二进制是 11111111-11111111-11111111-11111111
- byte类型的 -1(11111111) 提升为int类型,结果还是-1 ,由于int类型是32位,byte的-1转换为int类型的-1时,自动在byte类型-1的8个1前面全补1,这就导致了byte类型的-1转换为int类型的,结果还是-1.为了避免读取的字节数据八位都是1,再转换为int类型时结果还是-1的情况,可以在byte类型的的八位1前面都补0,即:
- byte -1 --->二进制是 11111111 转换int类型在八个1前面都补0,得到 00000000-00000000-00000000-11111111 (其十进制的值为255)。这样既可以保持原字节数据不变,而又避免了-1的情况。
- 让byte -1 --->二进制是 11111111 转换为int类型时,八个1前面都补0,可以通过
- 11111111-11111111-11111111-11111111
- & 00000000-00000000-00000000-11111111 (255)
- ---------------------------------------------------------------
- 00000000-00000000-00000000-11111111
- 这种方式实现,也就是代码中的 b&255;
- 而通过 b&255这种方式读取一个字节数据,返回一个int类型数据,即4个字节数据,那样的话,返回的数据应该是读取的数据的4倍,如果这样的话,将读取的数据写到另一个文件中时,就会出现写入的文件大小是读取文件大小的4倍,但是,事实上,读取的数据和返回的数据大小都是一样的,读取的文件大小和写入的文件大小都是一样的,那是应为read()方法读取数据时将byte类型提升为int类型,而写入数据时,write()方法也是写入字节数据,会将int类型强制转换为byte类型,即将int类型的最后八位写入到byte中,其他的都抛弃掉。
- wirte()方法写入数据时:
- int 类型 ------------------------------------------------------------------------------>byte
- 00000000-00000000-00000000-111111111 ------------------------------->11111111(只要后八位,前24位抛弃掉)*/
复制代码
|