PushbackInputStream 用于解析来自 InputStream 的数据。有时,在确定如何解释当前字节之前,您需要提前读取几个字节,以了解接下来会发生什么。PushbackInputStream 允许你这样做。实际上,它可以将读取的字节推回到流中。下次调用 read() 时,将再次读取这些字节。
PushbackInputStream 是 InputStream 的子类,因此它继承了 InputStream 的公共方法 read()、close() 等。PushbackInputStream 与 PushbackReader 类似,只是 PushbackInputStream 读取的是原始字节,而 PushbackReader 读取的是字符(文本)。
下面是一个简单的 PushbackInputStream 示例:
PushbackInputStream input = new PushbackInputStream( new FileInputStream("c:\\data\\input.txt")); int data = input.read(); input.unread(data);
调用 read() 就像从 InputStream 中读取字节一样。调用 unread() 会将字节推回 PushbackInputStream。下次调用 read() 时,将首先读取推回的字节。如果向 PushbackInputStream 推回多个字节,最新推回的字节将首先从 read() 返回,就像在堆栈中一样。
要使用 PushbackInputStream,必须先创建一个 PushbackInputStream 实例。下面是创建 PushbackInputStream 的示例:
PushbackInputStream input = new PushbackInputStream( new FileInputStream("c:\\data\\input.txt"));
请注意,PushbackInputStream 需要另一个 InputStream 作为其构造函数的参数。PushbackInputStream 将从底层 InputStream 读取字节。
您可以在 PushbackInputStream 的构造函数中设置未读字节数。以下是如何通过 PushbackInputStream 构造函数设置推回限制:
int pushbackLimit = 8; PushbackInputStream input = new PushbackInputStream( new FileInputStream("c:\\data\\input.txt"), pushbackLimit);
本例设置了一个 8 字节的内部缓冲区。这意味着在再次读取之前,每次最多可以取消读取 8 个字节。
您可以通过 PushbackInputStream 的 read() 方法读取字节,就像读取普通 InputStream 一样。下面是一个从 PushbackInputStream 读取字节的示例:
int aByte = pushbackInputStream.read(); while(aByte != -1) { //do something with aByte byte byteRead = (byte) aByte; aByte = pushbackInputStream.read(); }
请注意,一旦 PushbackInputStream 没有更多字节可从其底层 PushbackInputStream 读取,read() 方法将返回-1。
要将字节推回 PushbackInputStream,需要使用 unread() 方法。下面是一个将字节推回 PushbackInputStream 的示例:
int aByte = pushbackInputStream.read(); pushbackInputStream.unread(aByte); aByte = pushbackInputStream.read()
此示例首先从 PushbackInputStream 读取一个字节,然后将其推回 PushbackInputStream,最后通过 read() 调用再次读回该字节。
从 PushbackInputStream 读取完字节后,应记得关闭它。关闭 PushbackInputStream 也将关闭正在读取 PushbackInputStream 的 InputStream 实例。
关闭 PushbackInputStream 需要调用其 close() 方法。下面是关闭 PushbackInputStream 的过程:
pushbackInputStream.close();
您还可以使用 Java 7 中引入的 try-with-resources 结构。下面介绍如何使用 try-with-resources 结构使用和关闭 PushbackInputStream:
InputStream inputStream = new FileInputStream("data/data.bin"); try(PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream)){ int data = pushbackInputStream.read(); while(data != -1) { byte aByte = (byte) data; data = pushbackInputStream.read(); } }
请注意,这里不再有任何明确的 close() 方法调用。try-with-resources 结构已经解决了这个问题。
还请注意,第一个 FileInputStream 实例并没有在 try-with-resources 代码块中创建。这意味着 try-with-resources 块不会自动关闭 FileInputStream 实例。不过,当 PushbackInputStream 关闭时,它也会关闭从其读取的 InputStream 实例,因此 FileInputStream 实例将在 PushbackInputStream 关闭时被关闭。