🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 格式化内存输入 要读取格式化数据,我们可以使用 `DataInputStream`,它是一个面向字节的 I/O 类(不是面向字符的)。这样我们就必须使用 `InputStream` 类而不是 `Reader` 类。我们可以使用 `InputStream` 以字节形式读取任何数据(比如一个文件),但这里使用的是字符串。 ```java // iostreams/FormattedMemoryInput.java // {VisuallyInspectOutput} import java.io.*; public class FormattedMemoryInput { public static void main(String[] args) { try ( DataInputStream in = new DataInputStream( new ByteArrayInputStream( BufferedInputFile.read( "FormattedMemoryInput.java") .getBytes())) ) { while (true) System.out.write((char) in.readByte()); } catch (EOFException e) { System.out.println("\nEnd of stream"); } catch (IOException e) { throw new RuntimeException(e); } } } ``` `ByteArrayInputStream` 必须接收一个字节数组,所以这里我们调用了 `String.getBytes()` 方法。所产生的的 `ByteArrayInputStream` 是一个适合传递给 `DataInputStream` 的 `InputStream`。 如果我们用 `readByte()` 从 `DataInputStream` 一次一个字节地读取字符,那么任何字节的值都是合法结果,因此返回值不能用来检测输入是否结束。取而代之的是,我们可以使用 `available()` 方法得到剩余可用字符的数量。下面例子演示了怎么一次一个字节地读取文件: ```java // iostreams/TestEOF.java // Testing for end of file // {VisuallyInspectOutput} import java.io.*; public class TestEOF { public static void main(String[] args) { try ( DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("TestEOF.java"))) ) { while (in.available() != 0) System.out.write(in.readByte()); } catch (IOException e) { throw new RuntimeException(e); } } } ``` 注意,`available()` 的工作方式会随着所读取媒介类型的不同而有所差异,它的字面意思就是“在没有阻塞的情况下所能读取的字节数”。对于文件,能够读取的是整个文件;但是对于其它类型的“流”,可能就不是这样,所以要谨慎使用。 我们也可以通过捕获异常来检测输入的末尾。但是,用异常作为控制流是对异常的一种错误使用方式。