Reader是Java中读取字符流的抽象基类,核心是将字节按指定编码解码为Unicode字符;需显式指定字符集,依赖InputStreamReader实现解码;提供read()、skip()、mark()/reset()等方法及try-with-resources资源管理;常用子类包括FileReader、InputStreamReader、BufferedReader和StringReader。

Reader类是Java中专用于读取字符流的抽象基类,核心作用是把原始字节数据按指定编码规则解码为Unicode字符,让程序能安全、正确地处理文本内容。
解决文本读取中的编码问题
字节流(如InputStream)不关心字符含义,直接读二进制;而Reader自动完成“字节→字符”的转换。比如读一个UTF-8编码的中文文件,用FileInputStream可能得到乱码,但用InputStreamReader配合StandardCharsets.UTF_8就能准确还原每个汉字。
- 必须显式指定字符集,尤其在跨平台或非ASCII环境——FileReader默认用系统编码,极易出错
- 底层依赖InputStreamReader做字节到字符的桥接,它是Reader体系里真正实现解码逻辑的关键子类
提供统一的字符读取接口
无论数据来自文件、网络还是内存字符串,只要封装成对应的Reader子类,就能用相同方式读取:
- read():读单个字符,返回int值(0–65535),-1表示流结束
- read(char[] cbuf) 或 read(char[] cbuf, int off, int len):批量读入字符数组,效率远高于逐字符读
- skip(long n):跳过指定数量的字符(对解析跳过空白或标记很有用)
- ready():判断当前是否可无阻塞读取(适合非阻塞场景预判)
支持高级操作与资源管理
Reader不仅读数据,还提供控制读取行为和保障安全的能力:
立即学习“Java免费学习笔记(深入)”;
- mark(int readAheadLimit) 和 reset():在支持的子类(如BufferedReader)中可标记位置并回退,适合需要“试探性读取”的解析逻辑
- 实现Closeable接口,必须调用close()释放系统资源;推荐用try-with-resources自动关闭
- 所有方法都声明throws IOException,异常处理不可省略
常用子类分工明确,按需选用
不能直接new Reader,但它的子类覆盖了绝大多数文本读取场景:
- FileReader:快捷读文件,但默认编码不可控,仅适合本地调试
- InputStreamReader:最灵活,可包装任意InputStream(如Socket、HttpURLConnection),必须传Charset
- BufferedReader:性能关键角色,加缓冲提升IO效率,并独有readLine()方法,适合日志、配置、CSV等行式文本
- StringReader:将字符串当数据源,常用于单元测试或内存中临时解析










