Java I/O系列(一)InputStream与OutputStream源码分析及理解
1. InputStream
定义
字节输入流,是一个抽象类,核心是通过read()方法,从数据源中读取一个个字节出来,另有skip,mark功能

核心源码理解
源码:
public abstract int read() throws IOException;
理解:
1. 抽象方法,必须由子类实现;从什么地方读?数据源来自哪里?这个是由子类提供的,如FileInputStream是从文件中读,ByteArrayInputStream是从byte数组中读...
2. 每次读取都只会读取一个字节,一个byte出来,是有顺序的,读完这个字节,会自动跳到下一个字节等待读取
3. 注意返回值的定义是int,不是byte:如果有byte可读,就返回这个byte对应的无符号类型的值(0 - 255),返回值可以理解成某个“字符”的ASCII码值(如读取到A了,那么就会返回65);如果没有byte可读就直接返回-1
源码:
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
理解:
1. 这个方法比较好理解,循环调用read()方法,将读取到的int转换成byte,然后再放到参数b的特定位置(从off开始放,放len个,当然可能放不满len个,是等待读取的字节数而定);注意子类可能会重写这个方法,会有另外的实现
2. 返回值是实际读出来的字节数,如果没有则返回-1
2. OutPutStream
定义
字节输出流,也是一个抽象类,核心是通过write()方法,一个一个字节的写入到目的数据源中(由子类决定)

核心源码理解
源码:
public abstract void write(int b) throws IOException;
理解:
1. 抽象方法,必须由子类实现;写入到哪儿呢,由子类决定
2. 参数b是作为要写入的数据,是int类型不是byte类型;因为int是占4个字节共32位,这里规定的是取低8位,忽略高24位,所以最后写入的是一个字节;参数可以理解成某个ASCII码值的十进制,写入的就是对应的“字符”(如b=65时,写入的就是A)
源码:
public void write(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
理解:
1. 循环调用write()方法,将b[off] 到 b[off + len - 1] 的值写入到目的数据源
3. 总结:
1. 细心的可能会发现,read()方法返回值的范围是0 - 255,而byte本身范围是-128 - 127, 这样的转换其实是有符号byte类型到无符号类型的转换,做法是 int a = b & oxff, 其中b是有符号类型的byte 具体参考:https://www.jianshu.com/p/db85f033e75c
2. skip比较简单,其实现是将待跳过的部分读取出来而不使用;mark与reset结合使用都没有给出默认实现,由子类实现
3. 注意write(int b) 方法,是取b的低8位,忽略b的高24位
4. 问题:
1. 欢迎大家提出问题,共同交流学习!
5. 示例:
6. 参考:
1. https://www.jianshu.com/p/db85f033e75c
Java I/O系列(一)InputStream与OutputStream源码分析及理解的更多相关文章
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...
- Java 序列化和反序列化(二)Serializable 源码分析 - 1
目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...
- 图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)
图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize) 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步 ...
- Eureka 系列(04)客户端源码分析
Eureka 系列(04)客户端源码分析 [TOC] 0. Spring Cloud 系列目录 - Eureka 篇 在上一篇 Eureka 系列(01)最简使用姿态 中对 Eureka 的简单用法做 ...
- Java 序列化和反序列化(三)Serializable 源码分析 - 2
目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass ...
- Java 集合系列(四)—— ListIterator 源码分析
以脑图的形式来展示Java集合知识,让零碎知识点形成体系 Iterator 对比 Iterator(迭代器)是一种设计模式,是一个对象,用于遍历集合中的所有元素. Iterator 包含四个方法 ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- 【Java入门提高篇】Day26 Java容器类详解(八)HashSet源码分析
前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完 ...
随机推荐
- Chrome控制台毫无反应,打印不出信息了?
最近在使用console.log()方法的时候遇到一个奇怪的问题,打开chrome控制台想调试代码,结果控制台半天无反应,让我纳闷了半天.详情如图所示: 然后我又打开了新的标签页,不行!接着干脆关闭浏 ...
- MySQL数据库更改默认引擎为Innodb【配置】
InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定. 基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyIS ...
- Android ListView实现新闻客户端的新闻内容图文混排
布局文件: <LinearLayout xmlns:android="<a href="http://schemas.android.com/apk/res/andro ...
- 学习使用PRINCE2能带来什么益处?
使用PRINCE2有许多好处.它除了可重复使用.可升级.非常灵活之外,是在成百上千名有经验的项目经理们的帮助下,总结他们多年积累的实践经验和专业技术建立的. PRINCE2 开发于1989年并从此不断 ...
- 记录一次json转换的经历
需求:数据库里面的一个字段,存的是json数据,类似{‘name’:“name1”,'items':“[{code:0,name:'name2'}]”},{‘name’:“name3”,'items' ...
- SQL Server ->> 高可用与灾难恢复(HADR)技术之 -- Transaction Replication(事务复制)
复制类型: 1)事务型复制:通过复制事务日志到订阅点重做的方式,属于增量型复制: 2)合并型复制:通过触发器和元数据表追踪表数据改变,同样属于增量型复制: 3)快照型复制:通过创建数据库快照,并把快照 ...
- Excel开发之旅(三)——添加侧边工具栏
1. 添加自定义用户控件:选择项目添加新建项用户控件.修改文件名,点击添加即可. 2. 重复步骤1,再添加3个自定义控件,接下来我们在自定义用户控件上面添加一些工具箱组件 3. 由于我们添加的是侧边工 ...
- 内置的HTTP服务器【Modern PHP】
目录 启动服务器 配置服务器 路由器脚本 判断是否为内置的服务器 PHP5.4.0起,PHP内置了Web服务器.对本地开发是个极好的工具,便捷,无需安装WAMP.XAMP或大新那个web服务器,就能在 ...
- apt安装mysql
使用 APT 安装 MySQL 参考官方文档 apt-get install mysql-server 这将安装MySQL服务器的包,以及客户端和数据库公共文件的包. 在安装过程中,系统会要求您为ro ...
- DIY简单功能的torrentkitty种子爬虫
过完年回公司比较无聊,一不小心看到微博里美尤莉娅的图片,惊为天人,有图为证!!! 百度之原来这货以前叫小泉彩,貌似动了几个小手术换了个马甲重新出道了.你拍AV你家里知道么?.于是乎下了几个种子看了下, ...