news 2026/7/30 2:56:49

14、Reader的源码、FilterReader源码、PushbackReader源码(windows操作系统,JDK8)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
14、Reader的源码、FilterReader源码、PushbackReader源码(windows操作系统,JDK8)

14、Reader的源码、FilterReader源码、PushbackReader源码(windows操作系统,JDK8)

在Java I/O体系中,Reader是字符输入流的抽象基类,而FilterReaderPushbackReader则是基于装饰器模式的重要实现。本文将深入分析这三者的源码结构、设计思想及实际应用,并通过代码演示在 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 源码分析PushbackReaderFilterReader的子类,它增加了“回推”功能:允许将已读取的字符推回流中,以便再次读取。这在解析场景中非常有用。#### 核心源码解析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)方法- 在读取后立即将字符转换为大写,实现装饰器模式的功能增强—### ## 总结通过对ReaderFilterReaderPushbackReader的源码分析,我们可以看到 Java I/O 框架的设计智慧:1.抽象基类Reader定义了字符输入流的规范,使用模板方法模式减少子类实现负担。2.装饰器模式FilterReader中得到完美体现,使得功能可以灵活组合(例如PushbackReader包装FileReader)。3.PushbackReader提供了回推机制,在解析文本(如编译器前端)时非常实用,避免了字符的重复读取。4. 在 Windows 系统和 JDK8 环境下,这些类性能稳定,且通过lock对象实现了线程安全。掌握这些核心类的源码,不仅能帮助我们更高效地使用 Java I/O,还能启发我们在设计中运用模板方法和装饰器模式解决实际问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/30 2:52:49

基于机器学习的超市客户细分与营销策略分析13(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

基于机器学习的超市客户细分与营销策略分析13(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_ &#xff08;数据分析 数据可视化 聚类 机器学习&#xff09;含完整代码、真实数据集、报告与可视化图表&#xff0c;深度剖析超市客户细分与营销策…

作者头像 李华
网站建设 2026/7/30 2:49:33

机械设计项目|毕业设计|答疑辅导|瓜果切丝切片机的结构设计

标题&#xff1a;瓜果切丝切片机的结构设计 一、文档介绍 摘要&#xff1a;随着食品工业的快速发展&#xff0c;对高效、稳定的瓜果切丝切片机需求日益增长。本文聚焦于瓜果切丝切片机的结构设计与性能优化研究&#xff0c;旨在解决现有设备在切割效率、质量稳定性及能耗等方…

作者头像 李华
网站建设 2026/7/30 2:47:22

洋葱模型:从行为表象到动机内核的组织管理诊断工具

1. 从“洋葱”说起&#xff1a;一个被误解的组织管理工具第一次听到“洋葱模型”这个词&#xff0c;是在一个关于组织能力建设的内部研讨会上。当时&#xff0c;一位资深的人力资源总监在分析公司文化落地难的问题时&#xff0c;随手在白板上画了几个同心圆&#xff0c;然后说&…

作者头像 李华
网站建设 2026/7/30 2:47:12

Python爬虫实战:精准定位与下载在线视频源URL的完整指南

1. 项目缘起&#xff1a;从“想下载”到“能下载”的鸿沟 最近在技术社群里&#xff0c;经常看到有朋友问&#xff1a;“这个视频网站的视频怎么下载下来&#xff1f;” 或者 “我用浏览器开发者工具找到了一个视频链接&#xff0c;但下载下来只有几KB&#xff0c;根本不是视频…

作者头像 李华
网站建设 2026/7/30 2:46:44

线性回归核心 —— 误差项为什么必须服从高斯分布

一句话精华&#xff1a;线性回归的所有数学推导&#xff0c;都建立在 "误差项独立同分布且服从高斯分布" 这个假设之上。一、一元线性回归模型基础公式&#xff1a;yβ0β1xε→β0、β1&#xff1a;模型参数&#xff08;待求&#xff09;→ε&#xff1a;误差项&…

作者头像 李华