尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
17、FileReader的源码和使用方法详细分析(windows操作系统,JDK8)
17、FileReader的源码和使用方法详细分析windows操作系统JDK8一、FileReader 概述从字符流读取文件的基础在Java I/O体系中FileReader是一个专门用于从文件中读取字符数据的流类。它继承自InputStreamReader而InputStreamReader又继承自Reader抽象类。FileReader的设计目的是简化从文件读取字符的操作它将底层的字节流FileInputStream与字符编码转换通过InputStreamReader封装在一起让开发者能够直接以字符为单位读取文件内容。### 1.1 为什么需要 FileReader在Windows操作系统中文本文件的编码通常是GBK简体中文Windows默认编码或UTF-8。如果直接使用字节流如FileInputStream读取文本文件我们需要手动处理字节到字符的转换这容易导致乱码问题。FileReader自动使用平台默认字符编码在JDK 8的Windows系统中默认编码通常是GBK来解码字节流简化了文本文件读取操作。### 1.2 类层次结构java.lang.Object └── java.io.Reader (抽象类) └── java.io.InputStreamReader (桥接类) └── java.io.FileReader (具体实现类)FileReader没有直接实现自己的读取逻辑而是完全依赖于父类InputStreamReader提供的功能。这个设计遵循了“组合优于继承”的原则通过InputStreamReader将字节流转换为字符流。## 二、FileReader 核心源码分析基于JDK 8### 2.1 构造函数源码在JDK 8中FileReader的源码非常简洁共有三个构造函数java// FileReader.java (JDK 8)public class FileReader extends InputStreamReader { // 通过文件路径创建 FileReader public FileReader(String fileName) throws FileNotFoundException { super(new FileInputStream(fileName)); } // 通过 File 对象创建 FileReader public FileReader(File file) throws FileNotFoundException { super(new FileInputStream(file)); } // 通过 FileDescriptor 创建 FileReader public FileReader(FileDescriptor fd) { super(new FileInputStream(fd)); }}**关键点分析**- 每个构造函数内部都创建了一个FileInputStream对象然后调用父类InputStreamReader的构造函数。- InputStreamReader的构造函数会创建一个StreamDecoder对象用于执行实际的字节到字符的转换。- FileReader没有提供指定字符编码的构造方法它总是使用平台默认编码。这是FileReader的主要局限性。### 2.2 继承的方法由于FileReader直接继承自InputStreamReader它继承了以下关键方法| 方法 | 功能说明 ||------|----------|| read() | 读取单个字符返回字符的int值0-65535读取到末尾返回-1 || read(char[] cbuf) | 读取字符到数组中返回实际读取的字符数 || read(char[] cbuf, int off, int len) | 读取字符到数组的指定位置返回实际读取的字符数 || ready() | 判断流是否准备好被读取 || close() | 关闭流并释放相关资源 |### 2.3 字符编码处理机制在Windows系统中当使用FileReader读取文件时javasuper(new FileInputStream(fileName));父类InputStreamReader的构造函数中会调用java// InputStreamReader.java (JDK 8)public InputStreamReader(InputStream in) { super(in); try { sd StreamDecoder.forInputStreamReader(this, in, (String)null, Charset.defaultCharset()); } catch (UnsupportedEncodingException e) { throw new Error(e); }}这里Charset.defaultCharset()返回的是JVM启动时的默认字符集。在Windows系统上这个默认值通常是操作系统的编码如GBK。这意味着- 如果在中文Windows上创建的文件是UTF-8编码用FileReader读取可能会产生乱码。- 解决方案使用InputStreamReader并显式指定编码或者使用JDK 11引入的Files.newBufferedReader()方法。## 三、FileReader 基本使用方法### 3.1 基础示例按字符读取文件下面是一个完整的代码示例演示如何使用FileReader读取文本文件javaimport java.io.FileReader;import java.io.IOException;/** * FileReader 基础使用示例 * 演示按字符读取文件内容/public class FileReaderBasicExample { public static void main(String[] args) { // 创建FileReader对象使用try-with-resources自动关闭资源 try (FileReader reader new FileReader(“C:\example\test.txt”)) { int character; // 逐字符读取read()返回int类型的字符值 // 当读取到文件末尾时返回-1 System.out.println(“开始读取文件内容”); while ((character reader.read()) ! -1) { // 将int转换为char并输出 System.out.print((char) character); } System.out.println(“\n文件读取完成”); } catch (IOException e) { // 处理文件不存在或读取异常 System.err.println(“读取文件时发生错误” e.getMessage()); e.printStackTrace(); } }}**代码说明**1. 使用try-with-resources语法JDK 7自动关闭FileReader无需手动调用close()2. reader.read()返回的是int类型需要转换为char才能正确显示3. 循环条件character ! -1确保读取到文件末尾时停止### 3.2 使用缓冲数组提高效率逐字符读取效率较低推荐使用字符数组批量读取javaimport java.io.FileReader;import java.io.IOException;/* * 使用字符数组批量读取文件 * 提高读取效率/public class FileReaderBufferedExample { public static void main(String[] args) { // 创建字符数组作为缓冲区大小为1024个字符 char[] buffer new char[1024]; try (FileReader reader new FileReader(“C:\example\test.txt”)) { int bytesRead; // 实际读取的字符数 System.out.println(“开始读取文件使用缓冲区”); // 批量读取字符到缓冲区返回实际读取的字符数 while ((bytesRead reader.read(buffer)) ! -1) { // 将缓冲区中的字符转换为字符串 // 注意只转换实际读取的部分而不是整个缓冲区 String chunk new String(buffer, 0, bytesRead); System.out.print(chunk); } System.out.println(“\n文件读取完成”); // 输出缓冲区大小信息 System.out.println(“缓冲区大小” buffer.length 字符); } catch (IOException e) { System.err.println(“读取文件时发生错误” e.getMessage()); e.printStackTrace(); } }}**代码说明**1. 定义char[1024]缓冲区一次最多读取1024个字符2. reader.read(buffer)返回实际读取的字符数可能小于缓冲区大小3. 使用new String(buffer, 0, bytesRead)确保只转换有效内容4. 缓冲区大小建议设置为2的幂次如512、1024、2048与操作系统页大小匹配## 四、FileReader 的局限性与替代方案### 4.1 主要局限性1. **编码问题**无法指定字符编码始终使用平台默认编码2. **性能问题**没有内置缓冲机制逐字符读取效率低3. **功能单一**只能读取字符不支持跳过、标记等高级功能### 4.2 改进方案使用 BufferedReaderBufferedReader为FileReader添加了缓冲功能并提供readLine()等便捷方法javaimport java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;/* * 使用 BufferedReader 包装 FileReader * 提供行读取功能/public class BufferedReaderExample { public static void main(String[] args) { // 使用 BufferedReader 包装 FileReader try (BufferedReader bufferedReader new BufferedReader(new FileReader(“C:\example\test.txt”))) { String line; int lineNumber 0; System.out.println(“按行读取文件”); // readLine() 读取一行返回null表示文件末尾 while ((line bufferedReader.readLine()) ! null) { lineNumber; System.out.println(“第” lineNumber 行: line); } } catch (IOException e) { System.err.println(“读取文件时发生错误” e.getMessage()); e.printStackTrace(); } }}**优势分析**- 内部使用默认的8192字符缓冲区大幅提升读取性能- readLine()方法方便读取文本行自动处理换行符- 可以与其他Reader组合使用灵活性更高### 4.3 解决编码问题使用 InputStreamReader当需要指定编码时应直接使用InputStreamReaderjavaimport java.io.FileInputStream;import java.io.InputStreamReader;import java.io.BufferedReader;import java.io.IOException;import java.nio.charset.StandardCharsets;/* * 指定编码读取文件解决乱码问题 */public class EncodingAwareReaderExample { public static void main(String[] args) { // 显式指定UTF-8编码 try (BufferedReader reader new BufferedReader( new InputStreamReader( new FileInputStream(“C:\example\utf8_file.txt”), StandardCharsets.UTF_8))) { String line; while ((line reader.readLine()) ! null) { System.out.println(line); } } catch (IOException e) { System.err.println(“读取文件时发生错误” e.getMessage()); e.printStackTrace(); } }}## 五、总结FileReader是Java I/O体系中专门用于读取字符文件的便捷类它封装了FileInputStream和InputStreamReader简化了文本文件读取操作。通过本文的分析我们了解到1.核心机制FileReader通过继承InputStreamReader在内部创建FileInputStream并使用平台默认编码进行字节到字符的转换。2.使用方式既支持逐字符读取read()方法也支持批量读取read(char[])方法推荐使用字符数组或BufferedReader包装以提高效率。3.主要局限无法指定字符编码使用平台默认编码、没有内置缓冲机制、功能相对单一。4.最佳实践 - 对于简单的文本文件读取使用BufferedReader包装FileReader- 当需要指定编码时改用InputStreamReader配合FileInputStream- 在JDK 8环境下注意Windows系统的默认编码通常是GBK跨平台时需谨慎掌握FileReader的原理和使用方法是理解Java字符流体系的基础。在实际开发中我们通常会选择更高级的封装如Files.readAllLines()、Scanner等但理解底层实现有助于我们更好地处理I/O异常和编码问题。
RELATED

相关推荐

OnmyojiAutoScript:一键解放双手的阴阳师智能自动化方案

OnmyojiAutoScript:一键解放双手的阴阳师智能自动化方案

OnmyojiAutoScript:一键解放双手的阴阳师智能自动化方案 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 在快节奏的现代生活中,阴阳师玩家常常面临一个困…

📅 2026/10/20 14:51:38
三步实现NCM文件解密:C版网易云音乐转换终极指南

三步实现NCM文件解密:C版网易云音乐转换终极指南

三步实现NCM文件解密:C#版网易云音乐转换终极指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 还在为网易云音乐下载的NCM格式文件无法在其他播…

📅 2026/11/11 2:03:13
D3KeyHelper暗黑3按键助手:免费开源的游戏自动化终极指南

D3KeyHelper暗黑3按键助手:免费开源的游戏自动化终极指南

D3KeyHelper暗黑3按键助手:免费开源的游戏自动化终极指南 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏神3中繁琐的重复…

📅 2026/10/7 5:46:02
MORE NEWS

更多资讯

📰

之前考的证在外省能不能转过来 重庆市中级电工证多久拿证全解析

之前考的证在外省能不能转过来 重庆市中级电工证多久拿证全解析 之前考的证在外省能不能转过来?这是很多从外地来重庆工作的电工朋友最关心的问题,尤其是已经持有低压电工证但想升级到 重庆市中级电工证 的人。其实,证书在异地也能转过来,但…

📰

假电工证多不多网上查询最靠谱 建筑工人怎么避坑

假电工证多不多网上查询最靠谱 建筑工人怎么避坑 怕考不过白交培训费?最近在安阳工地干电工的王师傅就遇到这个问题。他花了几千块报了培训班,结果考试时发现题目和老师讲的根本对不上,最后挂科了,还不能退钱。其实,很多人不知道, 假电工证多不多…

📰

重新考低压电工证怎么报名怕考不过白交培训费

重新考低压电工证怎么报名怕考不过白交培训费 怕考不过白交培训费?别急,咱一步步来说清楚,尤其是信阳房建工程圈的兄弟,低压电工证这事,你得重视起来。今天咱们就聊清楚【重新考低压电工证】怎么报名,怎么准备,别让自己花冤枉钱。…

📰

考电工证是考哪些内容报名费多少钱

电工证考试内容全解析+官方报名入口找对不被坑 你是不是也担心不知道去哪报名怕被中介坑?其实现在考电工证已经不像以前那么难了,只要你能找到 官方报名入口…

📰

工地太忙根本没时间复习考试?内部消息:怎么线上查高级电工证全攻略来了

工地太忙根本没时间复习考试?内部消息:怎么线上查高级电工证全攻略来了 工地太忙根本没时间复习考试,这几乎是所有一线电工的共识。尤其在像商丘这样的工程大市,工地施工节奏快、任务重,很多电工都处于“边干边学”的状态。但你知道吗?…

📰

低压电工证太难了值不值得考?工地太忙根本没时间复习考试

低压电工证太难了值不值得考?工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这几乎是每个一线电工的共同声音。低压电工证考试内容多、题量大,很多人觉得复习起来吃力,甚至觉得低压电工证太难了,值不值得考?尤其是对于济源的中小施工企业负责…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬