PushbackInputStream 是用于回退字节的装饰器流,包装底层输入流并用缓冲区实现 unread() 推回功能;需预设足够缓冲大小,仅支持字节级退回,不支持字符编码与 mark/reset。

PushbackInputStream 是 Java IO 中用于“回退”字节的装饰器流,它本身不产生数据,而是包装一个底层输入流(如 FileInputStream 或 ByteArrayInputStream),并在读取后允许将已读的字节“推回”流中,供后续读取再次获取。
核心原理:缓冲 + 退回机制
它内部维护一个固定大小的字节数组缓冲区(默认 1 字节,可指定),当调用 unread(int b) 或 unread(byte[] b) 时,把字节存入缓冲区;下次调用 read() 会优先从该缓冲区取,缓冲区空了才去读底层流。这实现了逻辑上的“退回”效果。
基本使用步骤
- 创建底层输入流(例如从文件或字节数组)
- 用该流构造
PushbackInputStream,可指定缓冲区大小(建议 ≥ 预期最大退回字节数) - 正常调用
read()获取字节 - 若发现当前字节不是想要的(比如预读到分隔符、类型标识等),立即调用
unread()把它推回去 - 后续读取会先拿到刚推回的字节,就像没读过一样
典型应用场景举例
常用于需要“试探性读取”的解析场景,比如:
- 解析以特定字符开头的结构(如 XML 的
<、JSON 的{或[),先读一个字节判断类型,再决定走哪个解析分支——判断完需把该字节退回 - 跳过空白或注释时,读到非空白字符后要“还回去”,让主解析器统一处理
- 实现简单的词法分析器(lexer),预读下一个字符确认是否构成多字符操作符(如
==、!=)
注意事项与限制
- 缓冲区大小有限,
unread()超出容量会抛IOException;务必根据业务需要设置足够大的 buffer size(构造时传参) - 只能退回字节,不能退回字符(不处理编码);若需按字符退回,应使用
PushbackReader(对应 Reader 层) - 不支持标记(mark/reset),它和 mark/reset 是两套不同机制;
PushbackInputStream是单向“推回”,更轻量、更可控 - 调用
close()会同时关闭底层流,注意资源管理


















