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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马-张洋 中级黑马   /  2013-2-26 11:29  /  2798 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

以下内容摘自JDK1.6 API帮助文档.CHM

read
public int read()
         throws IOException从类 InputStream 复制的描述
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
子类必须提供此方法的一个实现。


指定者:
类 InputStream 中的 read
返回:
下一个数据字节;如果到达流的末尾,则返回 -1。
抛出:
IOException - 如果发生 I/O 错误。
另请参见:
portable 包中有关未实现特性的注释

read
public int read()
         throws IOException读取单个字符。在字符可用、发生 I/O 错误或者已到达流的末尾前,此方法一直阻塞。
用于支持高效的单字符输入的子类应重写此方法。


返回:
作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
抛出:
IOException - 如果发生 I/O 错误

为什么返回一个int。直接返回一个字节或者字符不是简单明了快速方便?

5 个回复

倒序浏览
首先,计算机是操作二进制码的,作为最底层的输入流不可能直接返回字符。(当然,Reader的read方法内部通过字符集转换为i字符)
其次,一个字节是8位,而在读取一个字节的时候可能会出现连续8个1的情况,8个1的二进制表示的应该是-1,则出现数据丢失。
所以,流通过对8位二进制码的字节升级为int(4字节,32位),前面补0.这样返回的就是32位的int值,因为前24位是0,所以原数据不变,只取到后8位有效数据。
回复 使用道具 举报
本帖最后由 谢洋 于 2013-2-26 12:27 编辑

read()方法内部将读取到的所有字节高位补0转为int返回, 这样做所有的数据都会是正数
这时就可以用-1表示流末尾了
而改变后的数据只要强转回byte, 就可以得到原有数据
如果不这样子会做发生的问题,在毕老师的模拟字节流流读取法方的视频中有详细的讲解,
具体不知道在那个视频了,反正是一个coyp my3文件例子,才copy一点就出现copy完的结果

因原是mp3存放的字节中可能出现n多个-1(11111111),如果以字节的形式返回 ,那么当读到第一个-1时,就会发生以为读到结结尾了。
而把-1(11111111)强转为int返回就变成00000000 00000000 0000000 11111111这这样就不会误以为到结尾了.
因为所有字节转型后都是正数,所以当返回的的是1111111 111111 111111 1111111 是就表结束了
这里说不清,还是多看视频就明白了
回复 使用道具 举报
本帖最后由 朱玉玺 于 2013-2-26 12:52 编辑

其实,说白了,我觉得他就是为了方便处理媒体文件。在媒体文件,比如Mp3、视频中,他们里边都是二进制数据,有可能出现“1111 1111“8个连续为1这样的一个字节,它的值是-1,如果我们的返回值类型是byte的,那么当他读到这样的一个字节时,read()方法返回的byte值也就是-1,而我们规定如果read()读到文件末尾时它的返回值才为-1,这时程序就会认为我们读到了文件末尾,但实际情况是我们才读到了媒体文件的一部分!那么怎么解决?java提供的方案是这样的:一.我先把byte提升为int,这是个自动类型提升的过程,自动类型提升的时候符号是跟着原来走的,原来是byte类型的-1,提升后是int类型,但值仍为-1,这就需要第二步了;二,这个提升后的int的高位补的是原来的符号,我让它不管最高位是1(负数)还是0(非负数),我让他提升后补的那24位都为0,怎么才能时提升后的24为都为0?用的是&255,经过第一次类型提升后,如果byte的值是-1,那么提升为int型的值也是-1,再&255,结果就成了255,把这个值作为返回值,从而解决了字节值为-1这种情况。
另外,需要注意的是,这里read把一个字节通过自动类型提升和类型转换后,变成了int,那么写入的时候,需要对这个int进行截取,以保持数据的原样性。输出流的write(int)
方法是有截取动作的,即:只取低8位,而把高24位舍弃。
java整这么麻烦,就是为了保证只用在文件读到末尾的那个文件结束标记时,才返回-1,其他任何情况,read的返回值都不是-1。
回复 使用道具 举报
朱玉玺 发表于 2013-2-26 12:47
其实,说白了,我觉得他就是为了方便处理媒体文件。在媒体文件,比如Mp3、视频中,他们里边都是二进制数据 ...

谢谢,大概听明白了,我再看看视频吧
回复 使用道具 举报
谢洋 发表于 2013-2-26 12:26
read()方法内部将读取到的所有字节高位补0转为int返回, 这样做所有的数据都会是正数
这时就可以用-1表示流 ...

谢谢,大概听明白了,我再看看视频吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马