Java I/O系列(一)InputStream源码分析及理解
程序员文章站
2022-04-14 15:12:40
定义 字节输入流,是一个抽象类,核心是通过read()方法,从数据源中读取一个个字节出来,另有skip,mark功能 核心源码理解 源码: 1 public abstract int read() throws IOException; 理解: 1. 从什么地方读?数据源来自哪里?这个是由子类提供的 ......
定义
字节输入流,是一个抽象类,核心是通过read()方法,从数据源中读取一个个字节出来,另有skip,mark功能
核心源码理解
源码:
1 public abstract int read() throws IOException;
理解:
1. 从什么地方读?数据源来自哪里?这个是由子类提供的,如FileInputStream是从文件中读,ByteArrayInputStream是从byte数组中读...
2. 每次读取都只会读取一个字节,一个byte出来,是有顺序的,读完这个字节,会自动跳到下一个字节等待读取
3. 注意返回值的定义是int,不是byte:a) 如果有byte可读,就返回这个byte对应的无符号类型的值(0 - 255)
b) 如果没有byte可读就直接返回-1
源码:
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 }
理解:
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.