A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

看了毕向东的IO流部分的字节流,自定义一个缓冲区,并且自定义以各read()方法,涉及到将byte转换成int向上转型,-1为什么要与上255呢?

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 神马都是浮云

查看全部评分

3 个回复

正序浏览
{:soso_e142:}欧拉,谢谢楼上的介绍。
回复 使用道具 举报
read:向上提升,write强制转换,两者保证原数据的不变化;
read方法返回的不是byte类型的字节而是int类型的原因是:避免了-1的发生,而write方法再将最低的一个字节写出去,保证了原数据的原样性。

byte-1提升了一个int类型,还是-1的原因:因为8个1前面补的是1导致的,那么只要在前面补0即可以保留原字节数据不变,又可以避免-1的出现,所以&255;

简单来说就是:在用输入流读取一个byte数据时,有时会出现连续8个1的情况,这个值在计算机内部表示-1,正好符合了流结束标记。所以为了避免流操作数据提前结束,将读到的字节进行int类型的扩展。保留该字节数据的同时,前面都补0,避免出现-1的情况。

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 很给力!

查看全部评分

回复 使用道具 举报

  1. import java.io.IOException;
  2. import java.io.InputStream;

  3. /**
  4. * 自定义字节缓冲流 简单模拟实现BufferedInputStream中的read()方法
  5. * */
  6. public class MyBufferedInputStream {

  7.         //持有一个InputStream对象实例
  8.         private InputStream in;
  9.         //定义一个字节数组,用于暂时缓存读取的数据
  10.         private byte[] buf = new byte[1024*4];
  11.         //定义一个指针
  12.         int pos = 0;
  13.         //定义计数器
  14.         int count = 0;

  15.         public MyBufferedInputStream(InputStream in){
  16.                 this.in = in;
  17.         }
  18.        
  19.         //定义一个myRead()方法,简单模拟实现BufferedInputStream中的read()方法
  20.         public int myRead() throws IOException{
  21.                 //如果计数器(字节数组的数据大小)为0,说明字节数组为空,没有数据,需要从硬盘上读取数据
  22.                 if(count == 0){
  23.                         count = in.read(buf);
  24.                         //如果硬盘上的数据已经全部读取完
  25.                         if(count < 0){
  26.                                 return -1;
  27.                         }
  28.                         //每次从硬盘上重新读取数据存储到字节数组中后都将指针重置
  29.                         pos = 0;
  30.                         //获取字节数组中的第一个字节数据
  31.                         byte b = buf[pos];
  32.                         //计数器减一
  33.                         count--;
  34.                         //指针后移一位
  35.                         pos++;
  36.                         //返回数据
  37.                         return b&255; //此次详解见下面(1)
  38.                 }else if(count > 0){
  39.                         byte b = buf[pos];
  40.                         //计数器减一
  41.                         count--;
  42.                         //指针后移一位
  43.                         pos++;
  44.                         //返回数据
  45.                         return b&255; //此次详解见下面(1)
  46.                 }
  47.                 return -1;
  48.         }
  49.         //定义一个关闭流的方法,用于模拟BufferedInputStream中的close()方法
  50.         public void close() throws IOException{
  51.                 in.close();
  52.         }
  53. }
  54. /*(1):读取字节数组中的数据都是byte类型,而最后返回值类型却是int类型,是将byte类型数据自动转换成int类型,是为了避免读取到的一个字节类型,其八位都是1的情况,

  55. 1个byte类型的数据,其八位都是1,意味着该字节的值为-1,转换int类型后也是-1,就会因为返回值是-1而误认为文件数据已经读取完。

  56. byte b = buf[pos]; b是byte类型,占八位,如果1个字节八位都是1,即11111111,转换成int类型,即十进制就是-1

  57. 如:byte -1    --->二进制是 11111111

  58.         int   -1   -----> 二进制是 11111111-11111111-11111111-11111111

  59. 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,即:

  60. byte -1    --->二进制是 11111111  转换int类型在八个1前面都补0,得到 00000000-00000000-00000000-11111111 (其十进制的值为255)。这样既可以保持原字节数据不变,而又避免了-1的情况。
  61. 让byte -1    --->二进制是 11111111 转换为int类型时,八个1前面都补0,可以通过

  62.    11111111-11111111-11111111-11111111

  63. & 00000000-00000000-00000000-11111111  (255)

  64. ---------------------------------------------------------------

  65. 00000000-00000000-00000000-11111111

  66. 这种方式实现,也就是代码中的 b&255;

  67. 而通过 b&255这种方式读取一个字节数据,返回一个int类型数据,即4个字节数据,那样的话,返回的数据应该是读取的数据的4倍,如果这样的话,将读取的数据写到另一个文件中时,就会出现写入的文件大小是读取文件大小的4倍,但是,事实上,读取的数据和返回的数据大小都是一样的,读取的文件大小和写入的文件大小都是一样的,那是应为read()方法读取数据时将byte类型提升为int类型,而写入数据时,write()方法也是写入字节数据,会将int类型强制转换为byte类型,即将int类型的最后八位写入到byte中,其他的都抛弃掉。

  68. wirte()方法写入数据时:

  69. int  类型  ------------------------------------------------------------------------------>byte

  70. 00000000-00000000-00000000-111111111  ------------------------------->11111111(只要后八位,前24位抛弃掉)*/
复制代码



评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 很给力!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马