“你好,阿米戈!今天,我们来熟悉一下输入/输出流。几天前我们粗略地了解了这个主题,但今天我们将对它进行深入探讨。输入/输出流分为 4 个类别:”
1) 流按方向分为:输入流和输出流
2) 流按数据类型分为:处理字节的数据流和处理字符的数据流。
下表中列出了这些分类:
输入流 | 输出流 | |
---|---|---|
使用字节 | InputStream | OutputStream |
使用字符 | Reader | Writer |
如果对象实现 InputStream 接口,则对象支持从接口顺序读取字节。
如果对象实现 OutputStream 接口,则对象支持向接口顺序写入字节。
如果对象实现 Reader 接口,则对象支持从接口顺序读取字符。
如果对象实现 Writer 接口,则对象支持向接口顺序写入字节。
输出流就像打印机。我们可以将文档输出到打印机。我们可以将数据输出到输出流。
就其本身而言,可以将输入流与扫描仪或电源插座进行比较。使用扫描仪,我们可以将文档输入计算机。或者,我们可以插入电源插座并从中接收电流。我们可以从输入流接收数据。
“在哪里使用它们呢?”
“这些类在 Java 中随处可见。我们熟悉的朋友 System.in 就是在 System 类中指定的 static InputStream 变量。
“真的吗?!这么说一直以来我都在使用 InputStream,但却没有意识到。System.out 也是流吗?”
“是的,System.out 是 System 类中的 static PrintStream(OutputStream 的后代)变量。”
“你是想告诉我,我一直在使用流,却没有意识到这一点对吗?”
“是的,这恰恰说明这些流是多么方便。你随便抓一个就可以使用。”
“但是 System.in 并非如此。我们必须经常向它添加 BufferedReader 或 InputStreamReader。”
“是的。但这也是有原因的。”
数据类型非常多,使用它们的方式也很多。因此,尽管标准 I/O 类几乎以相同的方式完成所有操作,但它们的数量却迅速增长。为了避免这种复杂性,Java 开发人员使用了抽象原理并将类分为许多很小的部分。
但是,你可以在需要时以连贯的方式将这些部分连接在一起,并获得非常复杂的功能。请看以下示例:
将流输出到工作台 |
|
将控制台输出流存储在单独的变量中。 将字符串输出到流。 |
|
在内存中创建动态(扩展)字节数组。 将其连接到新的输出流(PrintStream 对象)。 将字符串输出到流。 |
|
“老实说,这就像乐高玩具套装。只是我不清楚这些代码都在做什么。”
“现在先不用管这些。一切都在顺利进行。”
你需要记住以下几点:如果一个类实现 OutputStream 接口,则可以向它写入字节。跟你将数据输出到控制台几乎完全一样。它的作用就是它所完成的任务。使用我们的“乐高工具包”,我们不在乎每个单独零件的用途。我们关心的是,可供选择的大量零件使我们能够做出这么酷的东西。
“好的。那我们从哪开始呢?”
GO TO FULL VERSION