关于 java.io.PushbackReader 的部分笔记。本文演示代码段的执行环境基于JDK版本1.7。
概述
PushbackReader允许将读取到的字符内容再回退到输入流中(实际上这些内容被保存在了底层的一个缓冲区数组buf中),在调用read方法获取字符数据时会首先从缓冲区buf中获取内容,当从buf中无法得到所要求的内容时则向底层输入流获取数据。
继承关系
1 | // PushbackReader |
实现接口
类名 | 实现接口 |
---|---|
PushbackReader | Closeable, AutoCloseable,Readable |
PushbackReader
Constructor Summary
public PushbackReader(Reader in, int size)
1 | public PushbackReader(Reader in, int size) { |
初始化一个PushbackReader字符流。
public PushbackReader(Reader in)
1 | public PushbackReader(Reader in) { |
初始化一个PushbackReader字符流。
部分方法
private void ensureOpen()
1 | private void ensureOpen() throws IOException { |
检查当前buf是否有效且是否含有内容。
public int read()
1 | public int read() throws IOException { |
读取一个字符的内容并返回。通过synchronized关键字可以保证多线程环境下的线程安全。如果在调用read()方法之前曾经调用过unread()方法,那么buf中就存有unread()方法中传入的内容,在调用read()方法时需要首先读取缓冲区buf中的内容,即(pos < buf.length)。反之,直接从底层输出流中获取一个字符内容并返回。
public int read(char cbuf[], int off, int len)
1 | public int read(char cbuf[], int off, int len) throws IOException { |
读取长度为len的内容并保存到数组b中起始位置为off的空间中。通过synchronized关键字保证了多线程环境下的线程安全。第5 ~ 12行代码完成了参数的有效性校验。
第13行代码计算缓冲区buf的数据内容长度,如果有未读取的内容,那么将首先返回buf中的内容并保存到cbuf中。将数据保存到cbuf后更新计算pos、off、len值。如果buf中的内容未能满足len的长度要求,那么接着从底层输入流中获取数据。第23行代码依赖底层输入流将数据填充到cbuf中,计算实际读取的数据长度并返回。
public void unread(int c)
1 | public void unread(int c) throws IOException { |
回退一个字符到回退buf中。一旦执行了该方法,下一次调用read()方法获取的第一个字符会是该方法的入参c。通过synchronized关键字保证了多线程环境下的线程安全。如果pos到达了buf头部,那么意味着缓冲区buf已经没有空间容纳新的内容,所以向上抛出异常。反之,则将入参字符c保存到回退buf中。
public void unread(char cbuf[], int off, int len)
1 | public void unread(char cbuf[], int off, int len) throws IOException { |
将字符数组cbuf中的内容回退到缓冲区buf中。一旦执行了该方法,下一次调用read()方法获取的第一个字符会是cbuf[off],依次类推。通过synchronized关键字保证了多线程环境下的线程安全。通过调用系统方法System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)将cbuf中的内容复制保存到缓冲区buf中。
public boolean ready()
1 | public boolean ready() throws IOException { |
通知方法调用方当前输入流是否可提供字符内容。通过synchronized关键字保证了多线程环境下的线程安全。如果缓冲区buf中尚有可读取的字符内容,或者底层输入流可以继续通过read方法提供数据,那么则认为当前输入流可以继续对外提供数据内容。
public boolean markSupported()
1 | public boolean markSupported() { |
PushbackReader不支持标记重读操作,所以返回false。
public void mark(int readAheadLimit)
1 | public void mark(int readAheadLimit) throws IOException { |
PushbackReader不支持标记重读操作,所以在调用mark()方法时向上抛出异常。
public void reset()
1 | public void reset() throws IOException { |
PushbackReader不支持标记重读操作,所以在调用reset()方法时向上抛出异常。
public void close()
1 | public void close() throws IOException { |
关闭当前输入流。首先将底层输入流关闭,接着释放缓冲区buf占用的资源。
public long skip(long n)
1 | public long skip(long n) throws IOException { |
跳过n个长度的字符内容。n不可为负数,所以若传入一个负数长度,那么则向上抛出一个非法参数异常。第6行代码计算缓冲区buf中是否有回退的字符内容以及回退字符的长度。第8 ~ 10行代码表明需要跳过的长度n小于缓冲区buf中回退字符的长度,可以直接更新pos值完成跳过操作。反之则需要跳过缓冲区buf中的所有内容,同时跳过底层输入流中的若干字符内容以完成最终操作。最后计算实际跳过的字符长度并返回。
涉及基础知识点
- NIL
参考文献
- NIL