【Java部分源码分析之io篇】5.Reader
2017-07-27 00:00
316 查看
之前分析的都是字节的输入输出流,现在开始来看看字符的输入输出流。
Reader是字符输入流,与之对应的字节输入流是InputStream,后面会讲到有一个类利用字节输入流构建字符输入流,这个类就是InputStreamReader。与InputStream一样,Reader也是一个抽象类。它有一个成员变量lock,这个lock使得在这个流上的操作在多线程环境下可以安全的执行。来看一下这个成员变量。
接下来看一下它的两个构造方法。
两个构造方法没什么看头,都是在给lock赋值。
接下来看一下read方法。
可以看到最下面的抽象read方法没有任何实现,这个read方法是留到子类中实现的,一般来说,子类中的read方法是调用的本地方法,用native定义。其他三个重载read方法都是调用最后一个read方法,第一个还比较特殊,它的参数是NIO的一个对象CharBuffer,以后我们会讲解到这个对象的。
接下来看一下所有流操作都会有的skip,就是在流上往前走的字符数。这里定义了一个最大跳跃字符数为8192,也就是说一次跳跃最大可以跳8192个字符。同时skip在方法体内用了synchronized来控制,在多线程环境下也是安全的。如果跳跃小于8192个字符,则返回跳跃的字符数。
上面两个方法是比较少用,mark的作用用来标记输入流的一个位置,这样调用reset之后,输入流就能再次回到标记的位置,readlimit代表只能从输入流读取的数目。
close是个抽象方法,具体实现是在子类中实现。一般来说也是调用在JVM层面实现的本地方法。
Reader是字符输入流,与之对应的字节输入流是InputStream,后面会讲到有一个类利用字节输入流构建字符输入流,这个类就是InputStreamReader。与InputStream一样,Reader也是一个抽象类。它有一个成员变量lock,这个lock使得在这个流上的操作在多线程环境下可以安全的执行。来看一下这个成员变量。
/** * The object used to synchronize operations on this stream. For * efficiency, a character-stream object may use an object other than * itself to protect critical sections. A subclass should therefore use * the object in this field rather than <tt>this</tt> or a synchronized * method. */ protected Object lock;
接下来看一下它的两个构造方法。
protected Reader() { this.lock = this; } protected Reader(Object lock) { if (lock == null) { throw new NullPointerException(); } this.lock = lock; }
两个构造方法没什么看头,都是在给lock赋值。
接下来看一下read方法。
public int read(java.nio.CharBuffer target) throws IOException { int len = target.remaining(); char[] cbuf = new char[len]; int n = read(cbuf, 0, len); if (n > 0) target.put(cbuf, 0, n); return n; } public int read() throws IOException { char cb[] = new char[1]; if (read(cb, 0, 1) == -1) return -1; else return cb[0]; } public int read(char cbuf[]) throws IOException { return read(cbuf, 0, cbuf.length); } abstract public int read(char cbuf[], int off, int len) throws IOException;
可以看到最下面的抽象read方法没有任何实现,这个read方法是留到子类中实现的,一般来说,子类中的read方法是调用的本地方法,用native定义。其他三个重载read方法都是调用最后一个read方法,第一个还比较特殊,它的参数是NIO的一个对象CharBuffer,以后我们会讲解到这个对象的。
private static final int maxSkipBufferSize = 8192; private char skipBuffer[] = null; public long skip(long n) throws IOException { if (n < 0L) throw new IllegalArgumentException("skip value is negative"); int nn = (int) Math.min(n, maxSkipBufferSize); synchronized (lock) { if ((skipBuffer == null) || (skipBuffer.length < nn)) skipBuffer = new char[nn]; long r = n; while (r > 0) { int nc = read(skipBuffer, 0, (int)Math.min(r, nn)); if (nc == -1) break; r -= nc; } return n - r; } }
接下来看一下所有流操作都会有的skip,就是在流上往前走的字符数。这里定义了一个最大跳跃字符数为8192,也就是说一次跳跃最大可以跳8192个字符。同时skip在方法体内用了synchronized来控制,在多线程环境下也是安全的。如果跳跃小于8192个字符,则返回跳跃的字符数。
public void mark(int readAheadLimit) throws IOException { throw new IOException("mark() not supported"); } public void reset() throws IOException { throw new IOException("reset() not supported"); } abstract public void close() throws IOException;
上面两个方法是比较少用,mark的作用用来标记输入流的一个位置,这样调用reset之后,输入流就能再次回到标记的位置,readlimit代表只能从输入流读取的数目。
close是个抽象方法,具体实现是在子类中实现。一般来说也是调用在JVM层面实现的本地方法。
相关文章推荐
- 【Java部分源码分析之io篇】2.FileInputStream
- 【Java部分源码分析之io篇】1.InputStream
- 【Java部分源码分析之io篇】7.FileReader
- 【Java部分源码分析之io篇】6.InputStreamReader
- 【Java部分源码分析之io篇】0.传统IO输入输出流总览
- 【Java部分源码分析之io篇】4.FileOutputStream
- 【Java部分源码分析之io篇】3.OutputStream
- Java BufferedWriter BufferedReader 源码分析
- 【Java8源码分析】IO包-Reader、BufferedReader和Scanner总结
- Java Collections Framework之Arrays(method:sort(),binarySearch(),copyOf())部分源码分析(基于JDK1.6)
- 【Java部分源码分析之lang篇】1.Object
- Java中的InputStreamReader和OutputStreamWriter源码分析_动力节点Java学院整理
- java部分源码分析——LinkedList
- Java 中的FileReader和FileWriter源码分析_动力节点Java学院整理
- java的HashTable的部分源码分析
- Java IO:CharArrayReader使用及源码分析
- Java IO:PipedReader和PipedWriter使用详解及源码分析
- 《Java 源码分析》:Java NIO 之 Selector(第二部分selector.select())
- Java 自动装箱、拆箱机制及部分源码分析
- 【Java部分源码分析之lang篇】4.StringBuilder与StringBuffer(二)