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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘俊佳 中级黑马   /  2012-8-19 10:24  /  1200 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

毕老师视频里第19天-14-IO流(自定义字节流的缓冲区-read和write的特点)里面,讲到复制利用自定义缓冲区复制图片,复制的图片字节为0,这是怎样造成的?我没听懂

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

2 个回复

倒序浏览
复制图片 MP3,都是属于多媒体,里面是以二进制的形式存放的。
用字节的话来复制是8个二进制位。
而而进制里面只有 0 和1  。。
字节Read 方法,读取的是字节, 8位, 当字节是1111111的时候。
而返回的时候,是整数,32位, 前面补24个1111111111  ,
转成整数,就是负数了。
11111111 11111111 11111111 00000000
                                             11111111
2个相与的话
111111111111111111111111111111111





但是,程序里面,while,循环判断的,那个条件,是!= -1
但是多媒体里面的文件,都是字节啊,文件有很大,有8个1的字节,很正常,所有,
复制不了,或者复制不完整,是很正常的。

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 牛杨 于 2012-8-19 19:00 编辑

复制结果为 0字节 主要就是因为 读取图片的时候   把字节数据-1误当作读取结束标记-1了
下面是关于这个问题我总结的笔记  :
问题一:关于InputStream的读取一个字节的方法(public  int  read()),为什么这个方法返回的是int型的而不是byte型的呢?
        因为读取的是非文本类型的多媒体字节数据,而多媒体字节数据可以是任意的(比如可能是连续的 8个二进制1,也可能这8位表示的是负数等等),不像表示字符的字节数据那样可以在编码表中找到对应的位置。
        所以这种多媒体字节数据就有可能会出现一个字节是连续8个二进制1的情况,8个二进制1对应的十进制是-1 。(注意:这个-1本来是一个字节的数据,是数据,而不是读取的结束标记)
        但是如果不进行提升的话就会出现数据还没有读完,就读取到-1结束标记的情况。因为我们判断读取结束是通过结尾标记-1来确定的。
        所以,为了避免出现这种(将字节数据-1误当作读取结束标记-1的情况)就必须要将读到的字节(byte型)进行int类型的提升,但是提升的时候不能盲目提升,见下面问题二。
        问题二:为什么进行int类型提升的时候还要使用 & 0xff(或        & 0x00ff 、或 & 255),而不是直接仅仅使用默认的进行int型的强制类型转换 (int)呢?
        因为 假如使用的是直接进行int型的强制类型转换 (int),那么当读取到字节数据-1的时候(也就是连续的8个1的情况)。
        把byte型的-1强制转换到int型时转换成的还是-1(变成了 32个1的情况了),那么这个数据-1就又不能和读取结束标记-1区分开了。
        但是如果使用位运算 与的方法,把字节数据-1 & 0xff(或        & 0x00ff 、或 & 255),那么得到的就是高24位为 0 只有最后的8位为 1  ,也即在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。那么就能避免将字节数据-1误当作读取结束标记-1的情况了。
        而在写入数据时,只写该int类型数据的最低8位,忽略掉高24位。从而保证了字节数据的原样性!        
        经过 问题一 和 问题二 这两步联手——本质就是为了有效避免将字节数据-1误当作读取结束标记-1的情况,使字节数据-1和读取结束标记-1区分开。

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

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