14、Reader的源码、FilterReader源码、PushbackReader源码(windows操作系统,JDK8) 14、Reader的源码、FilterReader源码、PushbackReader源码windows操作系统JDK8在Java I/O体系中Reader是字符输入流的抽象基类而FilterReader和PushbackReader则是基于装饰器模式的重要实现。本文将深入分析这三者的源码结构、设计思想及实际应用并通过代码演示在 Windows 操作系统和 JDK8 环境下的使用。—### ## Reader 源码分析Reader位于java.io包中是所有字符输入流的超类。它定义了读取字符的规范主要方法包括-read()读取单个字符返回 int-1 表示流结束-read(char[] cbuf, int off, int len)读取字符到数组-close()关闭流#### 源码核心片段javapublic abstract class Reader implements Readable, Closeable { protected Object lock; protected Reader() { this.lock this; } protected Reader(Object lock) { if (lock null) { throw new NullPointerException(); } this.lock lock; } public int read() throws IOException { char[] cb new char[1]; if (read(cb, 0, 1) -1) return -1; else return cb[0]; } public abstract int read(char[] cbuf, int off, int len) throws IOException; public void close() throws IOException {}}关键点解读- 使用lock对象实现线程安全子类可以自定义锁-read()方法委托给read(char[], int, int)体现模板方法模式- 子类只需实现read(char[], int, int)和close()即可—### ## FilterReader 源码分析FilterReader是装饰器模式的典型代表它持有一个Reader引用并将所有读取操作委托给该Reader。其源码非常简洁javapublic class FilterReader extends Reader { protected Reader in; protected FilterReader(Reader in) { super(in); this.in in; } public int read() throws IOException { return in.read(); } public int read(char[] cbuf, int off, int len) throws IOException { return in.read(cbuf, off, len); } public void close() throws IOException { in.close(); }}设计亮点- 构造函数接收一个Reader对象存入in字段- 所有方法直接调用in的对应方法不做额外处理- 子类可通过覆盖特定方法添加功能如缓冲、回推—### ## PushbackReader 源码分析PushbackReader是FilterReader的子类它增加了“回推”功能允许将已读取的字符推回流中以便再次读取。这在解析场景中非常有用。#### 核心源码解析javapublic class PushbackReader extends FilterReader { private char[] buf; // 回推缓冲区 private int pos; // 当前读取位置 public PushbackReader(Reader in, int size) { super(in); if (size 0) throw new IllegalArgumentException(size 0); buf new char[size]; pos size; } public int read() throws IOException { if (pos buf.length) { return buf[pos]; } return super.read(); } public int read(char[] cbuf, int off, int len) throws IOException { if (pos buf.length) { int n Math.min(len, buf.length - pos); System.arraycopy(buf, pos, cbuf, off, n); pos n; return n; } return super.read(cbuf, off, len); } public void unread(char c) throws IOException { if (pos 0) throw new IOException(Pushback buffer overflow); buf[--pos] c; }}关键机制-buf数组存储回推的字符pos指向下一个可读位置-read()优先从buf中读取若缓冲区为空才从底层流读取-unread()将字符压入buf的前端递减pos—### ## 实战代码示例#### 示例1使用 PushbackReader 实现简易语法解析javaimport java.io.*;public class PushbackReaderDemo { public static void main(String[] args) throws IOException { String input a12b34c56; StringReader sr new StringReader(input); PushbackReader pr new PushbackReader(sr, 5); int ch; while ((ch pr.read()) ! -1) { if (Character.isDigit((char) ch)) { // 如果是数字回推字符并解析连续数字 pr.unread(ch); StringBuilder num new StringBuilder(); while ((ch pr.read()) ! -1 Character.isDigit((char) ch)) { num.append((char) ch); } System.out.println(解析到数字 num.toString()); // 如果读取到非数字字符也回推 if (ch ! -1) { pr.unread(ch); } } else { System.out.println(解析到字母 (char) ch); } } pr.close(); }}输出结果解析到字母a解析到数字12解析到字母b解析到数字34解析到字母c解析到数字56注释说明- 使用PushbackReader回推字符实现数字的连续读取- 当遇到数字时先回推再循环读取避免重复判断—#### 示例2自定义 FilterReader 实现字符过滤javaimport java.io.*;/** * 自定义过滤器将读取的字符转换为大写 */class UpperFilterReader extends FilterReader { protected UpperFilterReader(Reader in) { super(in); } Override public int read() throws IOException { int ch super.read(); return (ch -1) ? -1 : Character.toUpperCase((char) ch); } Override public int read(char[] cbuf, int off, int len) throws IOException { int n super.read(cbuf, off, len); for (int i off; i off n; i) { cbuf[i] Character.toUpperCase(cbuf[i]); } return n; }}public class FilterReaderDemo { public static void main(String[] args) throws IOException { String input hello, world!; StringReader sr new StringReader(input); UpperFilterReader ufr new UpperFilterReader(sr); char[] buffer new char[20]; int len ufr.read(buffer, 0, buffer.length); System.out.println(new String(buffer, 0, len)); // 输出: HELLO, WORLD! ufr.close(); }}输出结果HELLO, WORLD!注释说明- 继承FilterReader覆盖read()和read(char[], int, int)方法- 在读取后立即将字符转换为大写实现装饰器模式的功能增强—### ## 总结通过对Reader、FilterReader和PushbackReader的源码分析我们可以看到 Java I/O 框架的设计智慧1.抽象基类Reader定义了字符输入流的规范使用模板方法模式减少子类实现负担。2.装饰器模式在FilterReader中得到完美体现使得功能可以灵活组合例如PushbackReader包装FileReader。3.PushbackReader提供了回推机制在解析文本如编译器前端时非常实用避免了字符的重复读取。4. 在 Windows 系统和 JDK8 环境下这些类性能稳定且通过lock对象实现了线程安全。掌握这些核心类的源码不仅能帮助我们更高效地使用 Java I/O还能启发我们在设计中运用模板方法和装饰器模式解决实际问题。

本月热点