“你好,阿米戈!今天,我们来熟悉一下输入/输出流。几天前我们粗略地了解了这个主题,但今天我们将对它进行深入探讨。输入/输出流分为 4 个类别:”

1) 流按方向分为:输入流输出流

2) 流按数据类型分为:处理字节的数据流和处理字符的数据流。

下表中列出了这些分类:

输入流 输出流
使用字节 InputStream OutputStream
使用字符 Reader Writer

如果对象实现 InputStream 接口,则对象支持从接口顺序读取字节。

如果对象实现 OutputStream 接口,则对象支持向接口顺序写入字节。

如果对象实现 Reader 接口,则对象支持从接口顺序读取字符。

如果对象实现 Writer 接口,则对象支持向接口顺序写入字节。

输入/输出流 - 1

输出流就像打印机。我们可以将文档输出到打印机。我们可以将数据输出到输出流。

就其本身而言,可以将输入流与扫描仪或电源插座进行比较。使用扫描仪,我们可以将文档输入计算机。或者,我们可以插入电源插座并从中接收电流。我们可以从输入流接收数据。

“在哪里使用它们呢?”

“这些类在 Java 中随处可见。我们熟悉的朋友 System.in 就是在 System 类中指定的 static InputStream 变量。

“真的吗?!这么说一直以来我都在使用 InputStream,但却没有意识到。System.out 也是流吗?”

“是的,System.out 是 System 类中的 static PrintStreamOutputStream 的后代)变量。”

“你是想告诉我,我一直在使用流,却没有意识到这一点对吗?”

“是的,这恰恰说明这些流是多么方便。你随便抓一个就可以使用。”

“但是 System.in 并非如此。我们必须经常向它添加 BufferedReader 或 InputStreamReader。”

“是的。但这也是有原因的。”

数据类型非常多,使用它们的方式也很多。因此,尽管标准 I/O 类几乎以相同的方式完成所有操作,但它们的数量却迅速增长。为了避免这种复杂性,Java 开发人员使用了抽象原理并将类分为许多很小的部分。

但是,你可以在需要时以连贯的方式将这些部分连接在一起,并获得非常复杂的功能。请看以下示例:

将流输出到工作台
System.out.println("Hello");
将控制台输出流存储在单独的变量中。
将字符串输出到流。
PrintStream console = System.out;
console.println("Hello");
在内存中创建动态(扩展)字节数组。
将其连接到新的输出流(PrintStream 对象)。
将字符串输出到流。
ByteArrayOutputStream stream = new ByteArrayOutputStream();
PrintStream console = new PrintStream(stream);
console.println("Hello");

“老实说,这就像乐高玩具套装。只是我不清楚这些代码都在做什么。”

“现在先不用管这些。一切都在顺利进行。”

你需要记住以下几点:如果一个类实现 OutputStream 接口,则可以向它写入字节。跟你将数据输出到控制台几乎完全一样。它的作用就是它所完成的任务。使用我们的“乐高工具包”,我们不在乎每个单独零件的用途。我们关心的是,可供选择的大量零件使我们能够做出这么酷的东西。

“好的。那我们从哪开始呢?”