Java PushbackReader 类
最后修改时间:2025 年 4 月 16 日
java.io.PushbackReader
类是一个字符流读取器,允许将字符推回流中。这在解析输入时提供了超前查看功能。它封装了另一个 Reader
并增加了推回能力。
PushbackReader
维护一个内部缓冲区用于推回的字符。读取时,推回的字符会首先返回,然后再从底层流中读取。默认的推回缓冲区大小为 1 个字符,但可以自定义。
PushbackReader 类概述
PushbackReader
扩展了 FilterReader
并提供了基于字符的推回操作。关键方法包括读取操作和 unread(推回)方法。该类对于需要超前查看的解析场景非常有用。
public class PushbackReader extends FilterReader { public PushbackReader(Reader in); public PushbackReader(Reader in, int size); public int read(); public int read(char[] cbuf, int off, int len); public void unread(int c); public void unread(char[] cbuf); public void unread(char[] cbuf, int off, int len); public boolean ready(); public void close(); }
上面的代码显示了 PushbackReader
提供的关键方法。unread 方法允许将字符推回流中。read 方法首先使用推回的字符,然后再从底层流中读取。
创建 PushbackReader
PushbackReader 通过将其封装在另一个 Reader
中创建。您可以指定缓冲区大小或使用默认值 (1 个字符)。缓冲区大小决定了可以推回多少个字符。
import java.io.FileReader; import java.io.IOException; import java.io.PushbackReader; import java.io.Reader; public class Main { public static void main(String[] args) { try { // Create with default buffer size (1 character) Reader fileReader = new FileReader("data.txt"); PushbackReader pushbackReader1 = new PushbackReader(fileReader); // Create with custom buffer size (10 characters) Reader fileReader2 = new FileReader("data.txt"); PushbackReader pushbackReader2 = new PushbackReader(fileReader2, 10); System.out.println("Default pushback reader created"); System.out.println("Custom pushback reader (size 10) created"); pushbackReader1.close(); pushbackReader2.close(); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了创建 PushbackReader 的不同方法。第一个使用默认缓冲区大小 (1 个字符),而第二个指定 10 个字符。完成操作后始终关闭读取器以释放资源。当关闭 PushbackReader 时,底层的 FileReader 会自动关闭。
读取和推回字符
PushbackReader 的基本操作包括读取字符并选择性地将它们推回。unread 方法将字符推回流中。随后的读取将首先返回这些字符。
import java.io.IOException; import java.io.PushbackReader; import java.io.StringReader; public class Main { public static void main(String[] args) { String data = "ABCD"; try (PushbackReader reader = new PushbackReader(new StringReader(data))) { // Read first character int firstChar = reader.read(); System.out.println("First character: " + (char) firstChar); // Push it back reader.unread(firstChar); System.out.println("Character pushed back"); // Read again int sameChar = reader.read(); System.out.println("Read again: " + (char) sameChar); // Read next character int nextChar = reader.read(); System.out.println("Next character: " + (char) nextChar); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了基本的推回功能。读取第一个字符,然后将其推回,并再次读取。unread 方法允许将字符放回流中。推回缓冲区作为一个 LIFO(后进先出)结构运行。
推回多个字符
当使用更大的缓冲区创建时,PushbackReader 可以推回多个字符。unread 方法接受字符数组以进行批量推回操作。字符以它们在数组中出现的顺序被推回。
import java.io.IOException; import java.io.PushbackReader; import java.io.StringReader; public class Main { public static void main(String[] args) { String data = "1234567890"; try (PushbackReader reader = new PushbackReader(new StringReader(data), 5)) { // Read first 5 characters char[] buffer = new char[5]; reader.read(buffer); System.out.println("First read: " + new String(buffer)); // Push them back reader.unread(buffer); System.out.println("5 characters pushed back"); // Read again reader.read(buffer); System.out.println("Read again: " + new String(buffer)); // Try to push back more than buffer size try { char[] bigBuffer = new char[6]; reader.unread(bigBuffer); // Will throw IOException } catch (IOException e) { System.out.println("Cannot push back more than buffer size"); } } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了推回多个字符。读取器创建时带有 5 个字符的缓冲区。尝试推回超过缓冲区大小的字符会抛出 IOException。使用数组的 unread 操作对于批量推回场景非常有效。
使用 PushbackReader 进行解析
PushbackReader 特别适用于需要超前查看流的解析场景。检查字符后,如果它们与您要查找的内容不匹配,则可以将其推回。这使得解析逻辑更灵活。
import java.io.IOException; import java.io.PushbackReader; import java.io.StringReader; public class Main { public static void main(String[] args) { String data = "123abc456"; try (PushbackReader reader = new PushbackReader(new StringReader(data), 3)) { StringBuilder numbers = new StringBuilder(); int c; while ((c = reader.read()) != -1) { if (Character.isDigit((char) c)) { numbers.append((char) c); } else { // Push back non-digit and break reader.unread(c); break; } } System.out.println("Numbers found: " + numbers); // Read remaining characters char[] remaining = new char[6]; reader.read(remaining); System.out.println("Remaining: " + new String(remaining)); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了 PushbackReader 如何用于解析。它读取数字,直到找到非数字,然后将其推回。这允许单独处理非数字。推回功能简化了许多解析任务。
处理 Mark 和 Reset
与其他一些读取器不同,PushbackReader 不支持 mark 和 reset 操作。尝试使用这些方法将导致异常。推回功能对于许多用例来说具有类似的目的。
import java.io.IOException; import java.io.PushbackReader; import java.io.StringReader; public class Main { public static void main(String[] args) { String data = "test data"; try (PushbackReader reader = new PushbackReader(new StringReader(data))) { // Check if mark is supported System.out.println("Mark supported: " + reader.markSupported()); // Try to mark (will not throw exception but does nothing) reader.mark(10); // Read some data int c = reader.read(); System.out.println("Read: " + (char) c); // Try to reset (will throw IOException) try { reader.reset(); } catch (IOException e) { System.out.println("Reset not supported: " + e.getMessage()); } } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了 PushbackReader 不支持 mark/reset。markSupported 方法返回 false。尝试 reset 会抛出 IOException。对于类似的功能,请使用推回功能而不是 mark/reset。
使用 Pushback 读取行
PushbackReader 可用于实现自定义行读取逻辑。此示例显示了如何在处理行结尾时一致地读取行。Pushback 有助于检查行结尾字符。
import java.io.IOException; import java.io.PushbackReader; import java.io.StringReader; public class Main { public static void main(String[] args) { String data = "Line 1\r\nLine 2\nLine 3\rLine 4"; try (PushbackReader reader = new PushbackReader(new StringReader(data), 2)) { StringBuilder line = new StringBuilder(); int c; while ((c = reader.read()) != -1) { if (c == '\n') { System.out.println("Line found: " + line); line.setLength(0); } else if (c == '\r') { // Check for \r\n sequence int next = reader.read(); if (next != '\n') { reader.unread(next); } System.out.println("Line found: " + line); line.setLength(0); } else { line.append((char) c); } } // Print last line if not empty if (line.length() > 0) { System.out.println("Last line: " + line); } } catch (IOException e) { e.printStackTrace(); } } }
此示例实现了自定义行读取,该读取处理不同的行结尾 (\n, \r, \r\n)。推回功能允许检查 \r 之后的字符,以确定它是否是 \r\n 序列的一部分。这演示了 PushbackReader 在文本处理中的实际应用。
来源
在本文中,我们涵盖了 Java PushbackReader 类的基本方法和特性。了解这些概念对于处理需要在 Java 应用程序中具有超前查看能力的字符流至关重要。
作者
列出所有Java教程。