关于java字节流的read()方法返回值为int的思考
我们都知道java中io操作分为字节流和字符流,对于字节流,顾名思义是按字节的方式读取数据,所以我们常用字节流来读取二进制流(如图片,音乐 等文件)。问题是为什么字节流中定义的read()方法返回值为int类型呢?既然它一次读出一个字节数据为什么不返回byte类型呢?(不知道有没有人 和我有同样的困惑,不过既然有了问题咱就得解决。)
于是我翻阅了java的源码,下面先把源码贴出来(以BufferedInputStream/BufferedOutputStream为例):
//BufferedInputStream中的read()方法的实现
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;//这边getBufIfOpen()返回的是byte[],而& 0xff是为了保证由char类型向上拓展成int的时候,不进行符号拓展,而是0拓展。
}
从源码中我们得到的信息是直到getBufIfOpen()方法返回,我们得到的都是byte类型,可是为什么方法的最终返回值是int?
首先我先简单解释下符号扩展,这是指由byte向上转化成更宽的类型时,是扩展的符号位。这对于正数补0,负数补1,例如,定义byte b = -1;在计算机内部它是用八位1111 1111表示的,当扩展成32位整型的时候,一般情况下是1111 1111 1111 1111 1111 1111 1111 1111,即符号扩展,而对于无符号扩展,也称为0扩展,其结果是0000 0000 0000 0000 0000 0000 1111 1111(实际上这样一来值已经变成255了)。过于向上转型和强制向下转型的进一步讨论,我在以后再说。这里要说的是我们能从java源码中得到的第二 个信息,即上面的注释部分,read()方法的最后一行把读到的字节0扩展成了int,也就是说如果我们直接读出来这个值可能就是不对了。这里我又疑惑 了,为什么BufferedOutputStream中的writer()方法能正确读出字节呢?所以我再去查下对应的源码:
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b;
}
这里它果断的又将int强制转成了byte(截取后八位)。于是总结下现在得到的信息是,java字节流把byte转成int读出来再转回byte存起来。何必呢?
经过一番思考,我初步有了答案:在用输入流读取一个byte数据时,有时会出现连续8个1的情况,这个值在计算机内部表示-1,正 好符合了流结束标记。所以为了避免流操作数据提前结束,将读到的字节进行int类型的扩展。保留该字节数据的同时,前面都补0,避免出现-1的情况。而真 正读到文件最后结束是通过这句实现的:
[java] view plaincopy
if (pos >= count) return -1;
[java] view plaincopy
if (pos >= count) return -1;
所以我们使用的-1这个结束标志是通过这句返回的,而不是输入流读到了一个-1。
这样一来就解决了我们前面的疑惑,也证实了确实有这样实现的必要。对于字符流的读写也可以用类似的方法分析,这里不再赘述。
关于java字节流的read()方法返回值为int的思考的更多相关文章
- java 内存分析之方法返回值二
package Demo; class Point { private double x, y; public Point(double x, double y) { this.x = x; this ...
- java 内存分析之方法返回值及匿名对象一
package Demo; public class Point { private double x, y, z; public Point(double _x, double _y, double ...
- 慕课网-Java入门第一季-7-3 Java 中无参带返回值方法的使用
来源:http://www.imooc.com/code/1579 如果方法不包含参数,但有返回值,我们称为无参带返回值的方法. 例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值 ...
- Java 中无参带返回值方法的使用
如果方法不包含参数,但有返回值,我们称为无参带返回值的方法. 例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值为 int 类型的方法,执行的操作为计算两数之和,并返回结果 在 c ...
- java 反射获取方法返回值类型
//ProceedingJoinPoint pjp //获取方法返回值类型 Object[] args = pjp.getArgs(); Class<?>[] paramsCls = ne ...
- SpringMVC第五篇【方法返回值、数据回显、idea下配置虚拟目录、文件上传】
Controller方法返回值 Controller方法的返回值其实就几种类型,我们来总结一下-. void String ModelAndView redirect重定向 forward转发 数据回 ...
- JAVAEE——SpringMVC第二天:高级参数绑定、@RequestMapping、方法返回值、异常处理、图片上传、Json交互、实现RESTful、拦截器
1. 课前回顾 https://www.cnblogs.com/xieyupeng/p/9093661.html 2. 课程计划 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 ...
- Java的Object.hashCode()的返回值到底是不是对象内存地址?
关于这个问题,查阅了网上的资料,发现证明过程太繁琐,这里我用了反证法. java.lang.Object.hashCode()的返回值到底是不是对象内存地址? hashCode契约 说到这个问题,大家 ...
- C# 方法返回值的个数
方法返回值类型总的来说分为值类型,引用类型,Void 有些方法显示的标出返回值 public int Add(int a,int b) { return a+b; } 有些方法隐式的返回返回值,我们可 ...
随机推荐
- Linux EXT 文件系统 详解
上几章我们讲到了Linux启动的一些问题,接下来我们来看一下硬盘分割和EXT格式文件系统的问题.前面提到了分区表的问题,分区表位于MBR, 占用64个字节.所谓的硬盘分区也就是对硬盘进行规划,填写分区 ...
- 企业级分布式监控系统-Zabbix基础
1.基础分部 1.1Zabbix简介 Zabbix 是一个企业级的分布式开源监控方案. 1.2监控系统架构 C/S架构 客户端/服务器端,这种架构适合规模较小,处于同一地域的环境 C/P/S 客户端/ ...
- 数据库介绍(MySQL安装 体系结构、基本管理)
第1章 数据库介绍及mysql安装 1.1 数据库简介 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增.截取.更新.删除等操作. 所谓“数据库”系以一定方式 ...
- EntityFrameworkCore v1.1.1 问题汇总
随着宇宙第一IDE的最新版本发布[2017/3/7],AspNetCore 和EntityFrameworkCore(团队)都发布了最新的代码. 不过在我看来,这些到还不是最重要的.最重要的是dotn ...
- 洛谷 P3928 Sequence
题目描述 小强喜欢数列.有一天,他心血来潮,写下了三个长度均为n的数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种,波动数列. 阿米巴把他的喜好告诉了小强.小强便打算找出这三个数列内的最长波动数列. ...
- Solr6.5.0配置中文分词器配置
准备工作: solr6.5.0安装成功 1.去官网https://github.com/wks/ik-analyzer下载IK分词器 2.Solr集成IK a)将ik-analyzer-solr6.x ...
- 免费靠谱的 Let’s Encrypt 免费 https 证书申请全过程
申请 Let’s Encrypt证书的原因: 现在阿里云等都有免费的 https 证书,为什么还要申请这个呢(估计也是因为阿里云这些有免费证书的原因,所以 Let’s Encrypt 知道的人其实并不 ...
- Android - shape圆形画法(oval)
shape圆形画法(oval) 本文地址: http://blog.csdn.net/caroline_wendy 1. 创建一个目录drawable, 用于存放xml类型的图片资源; 2. 在dra ...
- 怎样获取HTML5视频的持续时间
HTML5视频的Bigger体验是非常令人振奋的,非常easy的道理,不用载入和依赖烦人的Flash或其它第三方插件来播放视频,也是大功一件.我们能够通过自己定义控件对视频进行显示和操控,当中一个常见 ...
- iOS 力学动画生成器UIKit Dynamics 之碰撞效果解说
UIKit Dynamic是iOS7 新增的一组类和方法.可赋予UIView逼真的行为和特征,不须要写动画效果那些繁琐的代码,让开发者可以轻松地改善应用的用户体验.一共同拥有6个可用于定制UIDyna ...