ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Java Reader 详解:从基础到实战

2026/9/6 8:21:11 拓冰建站 浏览量
Java Reader 详解:从基础到实战 1. 引言在 Java 的 I/O 体系中Reader是一个非常重要的抽象类它专门用于读取字符流。与InputStream字节流不同Reader以字符为单位进行读取天然支持 Unicode 字符集因此在处理文本文件、网络报文等场景时更加方便和安全。本文将从Reader的继承体系讲起逐步深入到常用实现类、典型用法、性能对比以及常见坑点帮助你全面掌握 Java 字符输入流的使用。2. Reader 是什么Reader是java.io包下的一个抽象类是所有字符输入流的基类。它的核心职责是从数据源文件、字符串、字节数组等读取字符数据。2.1 核心方法方法说明int read()读取单个字符返回 0~65535 的字符值读到末尾返回 -1int read(char[] cbuf)将字符读入数组返回实际读取的字符数abstract int read(char[] cbuf, int off, int len)将字符读入数组的指定区间返回实际读取的字符数long skip(long n)跳过 n 个字符boolean ready()判断是否可读void close()关闭流释放资源2.2 与 InputStream 的区别维度ReaderInputStream数据单位字符char字节byte字符集支持 Unicode自动解码不关心字符集适用场景文本文件、字符串、字符流图片、音频、二进制文件常用实现FileReader、BufferedReaderFileInputStream、BufferedInputStream3. Reader 的继承体系Reader的直接子类包括BufferedReader带缓冲的字符输入流支持按行读取InputStreamReader字节流到字符流的桥梁可指定字符集FileReader读取文件的字符流InputStreamReader的子类CharArrayReader从字符数组读取StringReader从字符串读取PipedReader管道字符流用于线程间通信Reader抽象类BufferedReaderInputStreamReaderFileReaderCharArrayReaderStringReaderPipedReader4. 常用实现类详解4.1 FileReaderFileReader用于读取文件中的字符数据适合读取文本文件。importjava.io.FileReader;importjava.io.IOException;publicclassFileReaderDemo{publicstaticvoidmain(String[]args){try(FileReaderreadernewFileReader(test.txt)){intch;while((chreader.read())!-1){System.out.print((char)ch);}}catch(IOExceptione){e.printStackTrace();}}}4.2 BufferedReaderBufferedReader为字符流提供缓冲功能显著提升读取效率并提供了readLine()方法可以按行读取文本。importjava.io.BufferedReader;importjava.io.FileReader;importjava.io.IOException;publicclassBufferedReaderDemo{publicstaticvoidmain(String[]args){try(BufferedReaderreadernewBufferedReader(newFileReader(test.txt))){Stringline;while((linereader.readLine())!null){System.out.println(line);}}catch(IOExceptione){e.printStackTrace();}}}4.3 InputStreamReaderInputStreamReader是字节流到字符流的桥梁可以指定字符集解码字节数据。importjava.io.FileInputStream;importjava.io.InputStreamReader;importjava.io.BufferedReader;importjava.io.IOException;importjava.nio.charset.StandardCharsets;publicclassInputStreamReaderDemo{publicstaticvoidmain(String[]args){try(BufferedReaderreadernewBufferedReader(newInputStreamReader(newFileInputStream(test.txt),StandardCharsets.UTF_8))){Stringline;while((linereader.readLine())!null){System.out.println(line);}}catch(IOExceptione){e.printStackTrace();}}}4.4 StringReaderStringReader将字符串作为字符流的数据源常用于解析字符串内容。importjava.io.StringReader;publicclassStringReaderDemo{publicstaticvoidmain(String[]args){StringcontentHello, Java Reader!;try(StringReaderreadernewStringReader(content)){intch;while((chreader.read())!-1){System.out.print((char)ch);}}catch(IOExceptione){e.printStackTrace();}}}5. 实战读取文件并统计字符下面通过一个完整的示例演示如何使用Reader读取文件并统计字符数、行数。importjava.io.BufferedReader;importjava.io.FileReader;importjava.io.IOException;publicclassFileStats{publicstaticvoidmain(String[]args){StringfilePathtest.txt;intcharCount0;intlineCount0;try(BufferedReaderreadernewBufferedReader(newFileReader(filePath))){Stringline;while((linereader.readLine())!null){lineCount;charCountline.length();}}catch(IOExceptione){e.printStackTrace();}System.out.println(总行数: lineCount);System.out.println(总字符数: charCount);}}6. 性能对比与优化建议6.1 单字符读取 vs 缓冲读取单字符读取read()每次调用都会触发底层 I/O 操作性能较差。使用BufferedReader后底层会一次性读取大量数据到缓冲区大幅减少 I/O 次数。6.2 指定字符集使用FileReader时默认使用平台默认字符集跨平台时可能出现乱码。建议使用InputStreamReader并显式指定字符集如UTF-8。6.3 使用 try-with-resourcesJava 7 引入的 try-with-resources 语法可以自动关闭流避免资源泄漏。7. 常见坑点7.1 乱码问题FileReader使用平台默认字符集在 Windows 上默认可能是 GBK读取 UTF-8 文件会乱码。解决方案是使用InputStreamReader指定UTF-8。7.2 read() 返回 -1 的判断read()返回int类型读到末尾返回 -1。注意不要将返回值直接强转为char再判断否则 -1 会被截断为 65535。7.3 忘记关闭流忘记关闭流会导致文件句柄泄漏。务必使用 try-with-resources 或在 finally 中关闭。8. 总结Reader是 Java 字符输入流的基石掌握它的继承体系、常用实现类以及性能优化技巧是写出健壮文本处理代码的关键。在实际开发中推荐优先使用BufferedReader配合InputStreamReader并显式指定字符集以获得最佳的性能与兼容性。