Java中IO框架——InputStream源码解析
2018-02-21 22:13
671 查看
InputStream 是所有字节输入流的父类。
它实现了 Closeable 接口:
Closeable 是可以关闭的数据源或目标。调用 close 方法可释放对象保存的资源。
下面来看 InputStream 的源码:
它实现了 Closeable 接口:
public interface Closeable extends AutoCloseable { // 关闭此流并释放与此流关联的所有系统资源。如果已经关闭该流,则调用此方法无效。 public void close() throws IOException; }
Closeable 是可以关闭的数据源或目标。调用 close 方法可释放对象保存的资源。
下面来看 InputStream 的源码:
属性
// 最大可跳过缓冲数组大小 private static final int MAX_SKIP_BUFFER_SIZE = 2048;
重要方法
read()
// 从输入流中读取数据的下一个字节,返回值的int其实是byte转化的int // 如果返回值为-1,说明没有可读的字节了 public abstract int read() throws IOException;
read(byte b[])
// 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中 public int read(byte b[]) throws IOException { // 调用下边的方法,无偏移的读取b数组长度等同的字节数 return read(b, 0, b.length); }
read(byte b[], int off, int len)
// 将输入流中读取最多len个字节,并将其存储在缓冲区数组b中 // 偏移量代表读取的字节从b数组哪个下标开始存入 public int read(byte b[], int off, int len) throws IOException { if (b == null) { // 如果字节数组b为空,抛出空指针异常 throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { // 如果偏移量或者长度不合适,跑出范围异常 throw new IndexOutOfBoundsException(); } else if (len == 0) { // 如果读取长度为0,直接返回0 return 0; } // 调用read()方法读取一个字节,读取的字节为c int c = read(); if (c == -1) { // 如果读取字节为-1,说明没有读取到字节,返回-1即可 return -1; } // 将读取到的字节,存入的数组b中偏移量off的下标位置中 b[off] = (byte)c; // 上边已经读取了一个字节,i从1开始,下边要开始循环读取共(len-1)个字节 int i = 1; try { for (; i < len ; i++) { // 读取下一个字节 c = read(); if (c == -1) { // 读取到-1说明读不到字节了,返回-1跳出循环即可 break; } // 下一个字节存入数组b的(off+i)下标处 b[off + i] = (byte)c; } } catch (IOException ee) { } // 返回读取到的字节个数 return i; }
skip(long n)
public long skip(long n) throws IOException { // 定义剩余要跳过的字节数量为remaining等于n long remaining = n; // 定义下边每次循环读取的字节数量为nr int nr; // 要跳过的字节数n小于等于0,说明不需要跳过字节则直接返回0 if (n <= 0) { return 0; } // 跳过的字节数size // 情况1,要跳过的字节数量大于2048,那么size就取2048 // 情况2,要跳过的字节数量小于2048,那么size就取要跳过的字节数量 int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); // 根据上一步确定的跳过的字节数size来定义字节数组 byte[] skipBuffer = new byte[size]; // 如果剩余要跳过的字节数量大于0就继续循环 while (remaining > 0) { // 从0开始,读取size和remaining间较小数的字节存入skipBuffer中,返回读取字节数量为nr // 这个循环中remaining即剩余跳过字节数量是不断减小的,所以有两种情况: // 情况1,对应上边的情况1,要跳过的字节数太大,大于2048 // 要跳过的字节数和剩余的字节数相比,如果剩余的还是太大,那么就读取size个数的字节 // 情况2,对应上边的情况2 // 要跳过的字节数大于等于剩余要跳过的字节数,那么就直接读取剩余跳过的字节即可 nr = read(skipBuffer, 0, (int)Math.min(size, remaining)); // 如果返回的字节数nr小于0,说明没有读取到字节,跳出循环 if (nr < 0) { break; } // 剩余的字节数量,等于要减去已经读取了的字节 // 如果是情况1,多次循环,每次都减去2048,直到剩余的小于2048了,剩下的一次读取即可 // 如果是情况2,一次循环的读取就OK了,remaining为0 remaining -= nr; } // 返回跳过的字节数 // 如果中途没有读取到输入流末尾,remaining为0,所以返回值为n,即要跳过的都跳过了 // 如果中途读取到了末尾,那么触发了break,此时remaining仍大于0, // 即此时跳过的自然少于需要跳过的大小,则实际跳过的自然要小 return n - remaining; }
available()
子类应该进行重写的类// 返回可读的字节数 public int available() throws IOException { return 0; }
close()
// 关闭输入流(该类未进行实现) public void close() throws IOException {}
mark(int readlimit)
// 标记该位置,以便使用reset()方法回滚回该位置 public synchronized void mark(int readlimit) {}
reset()
// 回滚回mark()标记的位置 public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); }
markSupported()
// 判断是否支持mark()、reset()方法 public boolean markSupported() { return false; }
相关文章推荐
- Java中IO框架——FilterInputStream源码解析
- Java中IO框架——FileInputStream源码解析
- Java中IO框架——OutputStream源码解析
- Java中IO框架——FileOutputStream源码解析
- java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例
- NIO框架之MINA源码解析(五):NIO超级陷阱和使用同步IO与MINA通信
- Java IO 系列源码分析——ByteArrayInputStream和ByteArrayOutputStream
- java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例
- Java_io体系之FilterInputStream/FilterOutputStream简介、走进源码及示例——07
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- Java_io体系之ObjectInputStream、ObjectOutputStream简介、走进源码及示例——11
- Java IO 之 InputStream源码
- Java_io体系之InputStream、OutputStream简介、走进源码——03
- Java IO:ByteArrayInputStream使用详解及源码分析
- Java_io体系之PipedInputStream、PipedOutputStream简介、走进源码及示例——06
- JDK 1.7 java.io 源码学习之ObjectInputStream和ObjectOutputStream
- Java Executor并发框架(十)Executor框架线程池源码解析
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- JDK中java.io.InputStream源码
- java.io.BufferedInputStream 源码分析