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教程。