Java 从流中读取byte的奇怪现象,出现负值,详解
来源:互联网 发布:南极人枕芯怎么样 知乎 编辑:程序博客网 时间:2024/05/22 01:42
其实一点都不奇怪,下面我们来详细分析
首先看下面一段代码,代码的意思是将128写入到文件中,再从文件中读出一个byte输出
File f = new File("f1"); FileOutputStream fos = new FileOutputStream(f); fos.write(128); fos.close(); FileInputStream fis = new FileInputStream(f); int a = fis.read(); System.out.println(a);
输出结果为:
128
这符合我们的直观感觉,写入128,读出来也是128
下面我们修改一下代码,将数据度入到byte数组里,看看输出会是什么样子,代码如下
File f = new File("f1"); FileOutputStream fos = new FileOutputStream(f); fos.write(128); fos.close(); FileInputStream fis = new FileInputStream(f); byte[] b = new byte[1]; fis.read(b, 0, 1); System.out.println(b[0]);
输出结果为
-128
好了,“奇怪”的现象出现了,这是为什么呢?
首先,我们需要了解一些基础知识,在Java中,byte的范围为 -128 ~ 127,并没有128这个数值;其次,读者需要了解一下负数在Java中如何表示(即原码、反码、补码的相关知识,请读者自行谷歌)。
下面,我们来分析一下出现 -128
的原因:
首先,
fos.write(128)
表示写入 “128” 所代表的字节,即1000 0000
,也就是说,文件中当前包含一个字节,8位依次为 1 0 0 0 0 0 0 0当我们调用
fis.read()
时,该方法会返回一个无符号byte,也就说直接将1000 0000
翻译为128,大家可以去看该方法的说明,返回值的范围为0 ~ 255;所以我们得到了 128 的输出;当我们调用
fis.read(b, 0, 1)
时,相当于把文件中第一个字节读入到了b[0]中,此时b[0]的二进制表示为1000 0000
,根据负数在Java中的表示方法,我们可以计算出,该二进制序列的数值为 -128,也就是说这个过程并没有将其转化为无符号数值的过程,所以我们得到了 -128 的输出。
那么,我们如何解决这个问题呢?
首先,我们需要看一下fos.write(int a)
这个方法,它的功能是写入a代表的byte值,也就是说,该函数实际上是将a 的后八位写入到文件中 , 所以作者建议在使用该方法时,为了避免产生歧义,a 的范围最好在 0 ~ 255 之间,初学者最好在 0 ~ 127 之间。(具体原因可以结合负数的表示规则自己想想哦~)。
回归正题,我们如何解决上文中的问题呢,即 “写入128、读出-128” 的问题,我们可以用下面的代码来解决。
File f = new File("f1"); FileOutputStream fos = new FileOutputStream(f); fos.write(128); fos.close(); FileInputStream fis = new FileInputStream(f); byte[] b = new byte[1]; fis.read(b, 0, 1); System.out.println(b[0] & 0xff);
也就是说,用
b[0] & 0xff
的方法得到b[0]的无符号值。插入一个小问题,就是,
b[0] | 0xff
得到的是一个负值,而 & 得到的却是一个正值。这里根据作者的猜测,可能是如下原因,主要和 & 运算的步骤有关:进行
b[0] & 0xff
运算时的步骤如下:
- 因为0xff默认应该用int来保存,所以首先将 b[0] 强制转化为 int 类型表示,b[0] 的数值为-128,所以其二进制表示为11111111 11111111 11111111 10000000
- 0xff的二进制表示为 00000000 00000000 00000000 11111111
- 这两个数做 & 运算后,得到 00000000 00000000 00000000 10000000,其表示的值为128
“或 运算”的过程类似,读者可以自己推理一下
- Java 从流中读取byte的奇怪现象,出现负值,详解
- Java String中split的奇怪现象
- java的奇怪现象
- Redhat中制作RPM包出现的奇怪现象
- Python中奇怪的现象
- java会合构架中TreeSet的奇怪现象两个
- java性能测试中遇到的奇怪现象
- java中byte(负值)作&运算时0xff的作用
- Access中Select 备注类型的文本时出现的奇怪现象
- MyEclipse中出现的一个非常奇怪的现象,高手请看
- Java里面遇到的奇怪的现象!!!
- c++中 堆的一个奇怪现象
- JQuery中DIV的奇怪现象
- ie8中一个很奇怪的现象。
- python中all()的“奇怪”现象
- 讨论java两个奇怪的语法现象
- java Calendar类 一个奇怪的现象
- C#两个日期控件的比较,出现奇怪的现象
- Android ViewDragHelper完全解析 自定义ViewGroup神器
- android listview 下拉头部图片拉伸
- 169. Majority Element
- CentOS 6.5下利用Rsyslog+LogAnalyzer+MySQL部署日志服务器
- 几种简单排序的实现
- Java 从流中读取byte的奇怪现象,出现负值,详解
- Android Studio通过Gradle命令来编译生成打包APK
- PAT (Top Level) Practise 1011 Cut Rectangles (35)
- mac 升级自带svn
- checkenc - 自动文本编码识别
- Java中Date插入数据库的一些问题总结(二)
- Variably modified array at file scope
- 桂林电子科技大学操作系统课程设计(二)
- CodeForces 367A-Sereja and Algorithm【规律】