欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java I/O系列(一)InputStream源码分析及理解

程序员文章站 2022-04-14 15:12:40
定义 字节输入流,是一个抽象类,核心是通过read()方法,从数据源中读取一个个字节出来,另有skip,mark功能 核心源码理解 源码: 1 public abstract int read() throws IOException; 理解: 1. 从什么地方读?数据源来自哪里?这个是由子类提供的 ......

定义


 字节输入流,是一个抽象类,核心是通过read()方法,从数据源中读取一个个字节出来,另有skip,mark功能

Java I/O系列(一)InputStream源码分析及理解

 

 

核心源码理解


源码:

 1 public abstract int read() throws IOException; 

理解:

1. 从什么地方读?数据源来自哪里?这个是由子类提供的,如FileInputStream是从文件中读,ByteArrayInputStream是从byte数组中读...

2. 每次读取都只会读取一个字节,一个byte出来,是有顺序的,读完这个字节,会自动跳到下一个字节等待读取

3. 注意返回值的定义是int,不是byte:a) 如果有byte可读,就返回这个byte对应的无符号类型的值(0 - 255)

                  b) 如果没有byte可读就直接返回-1

源码:

Java I/O系列(一)InputStream源码分析及理解
 1 public int read(byte b[], int off, int len) throws IOException {
 2         if (b == null) {
 3             throw new NullPointerException();
 4         } else if (off < 0 || len < 0 || len > b.length - off) {
 5             throw new IndexOutOfBoundsException();
 6         } else if (len == 0) {
 7             return 0;
 8         }
 9 
10         int c = read();
11         if (c == -1) {
12             return -1;
13         }
14         b[off] = (byte)c;
15 
16         int i = 1;
17         try {
18             for (; i < len ; i++) {
19                 c = read();
20                 if (c == -1) {
21                     break;
22                 }
23                 b[off + i] = (byte)c;
24             }
25         } catch (IOException ee) {
26         }
27         return i;
28     }
View Code

理解:

1. 这个方法比较好理解,循环调用read()方法,将读取到的int转换成byte,然后再放到参数b的特定位置(从off开始放,放len个,当然可能放不满len个,是等待读取的字节数而定);注意子类可能会重写这个方法,会有另外的实现

 

总结:


 1. 细心的可能会发现,read()方法返回值的范围是0 - 255,而byte本身范围是-128 - 127, 这样的转换其实是有符号byte类型到无符号类型的转换,做法是 int a = b & oxff, 其中b是有符号类型的byte   具体参考:

2. skip比较简单,其实现是将待跳过的部分读取出来而不使用;mark与reset结合使用都没有给出默认实现,由子类实现

 

问题:


 

 

参考:


 1.