黑马程序员技术交流社区
标题:
复制图片的问题
[打印本页]
作者:
刘俊佳
时间:
2012-8-19 10:24
标题:
复制图片的问题
毕老师视频里第19天-14-IO流(自定义字节流的缓冲区-read和write的特点)里面,讲到复制利用自定义缓冲区复制图片,复制的图片字节为0,这是怎样造成的?我没听懂
作者:
刘圣伟
时间:
2012-8-19 17:39
复制图片 MP3,都是属于多媒体,里面是以二进制的形式存放的。
用字节的话来复制是8个二进制位。
而而进制里面只有 0 和1 。。
字节Read 方法,读取的是字节, 8位, 当字节是1111111的时候。
而返回的时候,是整数,32位, 前面补24个1111111111 ,
转成整数,就是负数了。
11111111 11111111 11111111 00000000
11111111
2个相与的话
111111111111111111111111111111111
但是,程序里面,while,循环判断的,那个条件,是!= -1
但是多媒体里面的文件,都是字节啊,文件有很大,有8个1的字节,很正常,所有,
复制不了,或者复制不完整,是很正常的。
作者:
牛杨
时间:
2012-8-19 18:56
本帖最后由 牛杨 于 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区分开。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2