Java Reader 类
最后修改时间:2025 年 4 月 16 日
java.io.Reader
类是一个用于读取字符流的抽象类。它是 Java 中所有字符输入流类的基类。与字节流不同,Reader 处理 16 位 Unicode 字符。
Reader
提供了从各种源读取字符的基本方法。子类实现这些方法以用于特定的输入类型,如文件、字符串或管道。该类在内部处理字符编码转换。
Reader 类概述
Reader
是一个抽象类,定义了基本的字符输入操作。关键方法包括读取字符、跳过字符以及 mark/reset 功能。 所有方法都会抛出 IOException 以表示 I/O 错误。
public abstract class Reader implements Readable, Closeable { public int read(); public int read(char[] cbuf); public abstract int read(char[] cbuf, int off, int len); public long skip(long n); public boolean ready(); public boolean markSupported(); public void mark(int readAheadLimit); public void reset(); public abstract void close(); }
上面的代码显示了 Reader
提供的关键方法。 这些方法允许从各种来源读取字符数据。 具体子类必须实现用于特定输入类型的抽象方法。
创建 Reader
Reader 是抽象的,因此我们使用其子类,如 FileReader 或 StringReader。 这些为不同的字符源提供了具体的实现。 完成后始终关闭 Reader 以释放资源。
import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; public class Main { public static void main(String[] args) { try { // Create FileReader Reader fileReader = new FileReader("text.txt"); // Create StringReader Reader stringReader = new StringReader("Hello Reader"); System.out.println("FileReader and StringReader created"); fileReader.close(); stringReader.close(); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了创建两个常见的 Reader 实现。 FileReader 从文件读取,而 StringReader 从字符串读取。 两者都是 Reader 的子类。 close 方法释放所有系统资源。
使用 Reader 读取字符
读取字符的最简单方法是使用 read() 方法。 它以 int 形式返回单个字符,如果到达流末尾则返回 -1。 这对于逐字符处理文本很有用。
import java.io.IOException; import java.io.StringReader; import java.io.Reader; public class Main { public static void main(String[] args) { try (Reader reader = new StringReader("Java Reader")) { int charData; while ((charData = reader.read()) != -1) { System.out.print((char) charData); } System.out.println("\n\nReading complete"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了如何从 StringReader 中逐个字符读取。 try-with-resources 语句确保正确关闭流。 每个字符都从 int 强制转换为 char 以进行显示。 循环持续到 read 返回 -1。
将字符读取到数组中
为了获得更好的性能,一次将多个字符读入一个 char 数组。 这减少了方法调用并提高了效率。 read 方法返回实际读取的字符数。
import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class Main { public static void main(String[] args) { try (Reader reader = new FileReader("text.txt")) { char[] buffer = new char[1024]; int charsRead; while ((charsRead = reader.read(buffer)) != -1) { System.out.println("Read " + charsRead + " characters"); System.out.println(new String(buffer, 0, charsRead)); } System.out.println("File reading complete"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了批量读取到 char 数组中。 可以根据需要调整缓冲区大小 (1024)。 charsRead 值指示实际读取了多少字符。 String 构造函数将缓冲区的相关部分转换为字符串。
Mark 和 Reset 功能
某些 Reader 实现支持 mark 和 reset 操作以重新读取数据。 mark 方法标记当前位置,reset 返回到该位置。 readAheadLimit 指定在 mark 变为无效之前可以读取多少个字符。
import java.io.IOException; import java.io.StringReader; import java.io.Reader; public class Main { public static void main(String[] args) { try (Reader reader = new StringReader("Java Reader Mark Example")) { // Read first 5 characters char[] firstPart = new char[5]; reader.read(firstPart); System.out.println("First part: " + new String(firstPart)); // Mark current position reader.mark(10); // Allow 10 chars to be read before mark invalid // Read next 5 characters char[] secondPart = new char[5]; reader.read(secondPart); System.out.println("Second part: " + new String(secondPart)); // Reset back to mark reader.reset(); // Read again from marked position reader.read(secondPart); System.out.println("Second part after reset: " + new String(secondPart)); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了 StringReader 的 mark 和 reset 功能。 在读取前 5 个字符后设置 mark。 读取接下来的 5 个字符后,reset 返回到标记的位置。 并非所有 Reader 都支持 mark/reset - 请使用 markSupported() 检查。
跳过流中的字符
skip 方法允许跳过流中指定数量的字符。 这比读取和丢弃数据更有效。 实际跳过的字符数可能少于请求的字符数。
import java.io.IOException; import java.io.StringReader; import java.io.Reader; public class Main { public static void main(String[] args) { try (Reader reader = new StringReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ")) { // Skip first 10 characters long skipped = reader.skip(10); System.out.println("Skipped " + skipped + " characters"); // Read next character int nextChar = reader.read(); System.out.println("Next character: " + (char) nextChar); // Skip beyond end of stream skipped = reader.skip(20); System.out.println("Skipped " + skipped + " characters (end approached)"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了如何在 Reader 中跳过字符。 第一个 skip 越过前 10 个字母。 第二个 skip 尝试跳过 20 个字符,但仅跳过剩余的字符。 该方法返回实际跳过的数量。
使用 ready() 检查就绪状态
ready 方法检查 Reader 是否已准备好读取。 如果下一次读取不会阻塞输入,则返回 true。 这对于非阻塞 I/O 检查很有用。
import java.io.IOException; import java.io.StringReader; import java.io.Reader; public class Main { public static void main(String[] args) { try (Reader reader = new StringReader("Ready Check")) { System.out.println("Reader ready: " + reader.ready()); // Read all characters while (reader.ready()) { System.out.print((char) reader.read()); } System.out.println("\nReader after reading: " + reader.ready()); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了使用 ready() 检查 Reader 状态。 当字符可用时,该方法返回 true。 读取所有字符后,ready() 返回 false。 请注意,返回 false 并不一定意味着流的结尾。
来源
在本文中,我们介绍了 Java Reader 类的基本方法和功能。 理解这些概念对于在 Java 应用程序中使用字符输入操作至关重要。
作者
列出所有Java教程。