# 10.1 输入和输出
可将Java库的IO类分割为输入与输出两个部分,这一点在用Web浏览器阅读联机Java类文档时便可知道。通过继承,从`InputStream`(输入流)派生的所有类都拥有名为`read()`的基本方法,用于读取单个字节或者字节数组。类似地,从`OutputStream`派生的所有类都拥有基本方法`write()`,用于写入单个字节或者字节数组。然而,我们通常不会用到这些方法;它们之所以存在,是因为更复杂的类可以利用它们,以便提供一个更有用的接口。因此,我们很少用单个类创建自己的系统对象。一般情况下,我们都是将多个对象重叠在一起,提供自己期望的功能。我们之所以感到Java的流库(Stream Library)异常复杂,正是由于为了创建单独一个结果流,却需要创建多个对象的缘故。
很有必要按照功能对类进行分类。库的设计者首先决定与输入有关的所有类都从`InputStream`继承,而与输出有关的所有类都从`OutputStream`继承。
## 10.1.1 `InputStream`的类型
`InputStream`的作用是标志那些从不同起源地产生输入的类。这些起源地包括(每个都有一个相关的`InputStream`子类):
(1) 字节数组
(2) `String`对象
(3) 文件
(4) “管道”,它的工作原理与现实生活中的管道类似:将一些东西置入一端,它们在另一端出来。 (5) 一系列其他流,以便我们将其统一收集到单独一个流内。
(6) 其他起源地,如Internet连接等(将在本书后面的部分讲述)。
除此以外,`FilterInputStream`也属于`InputStream`的一种类型,用它可为“析构器”类提供一个基类,以便将属性或者有用的接口同输入流连接到一起。这将在以后讨论。
```
Class
Function
Constructor Arguments
How to use it
ByteArray-InputStream
Allows a buffer in memory to be used as an InputStream.
The buffer from which to extract the bytes.
As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
StringBuffer-InputStream
Converts a String into an InputStream.
A String. The underlying implementation actually uses a StringBuffer.
As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
File-InputStream
For reading information from a file.
A String representing the file name, or a File or FileDescriptor object.
As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
```
| 类 | 功能 | 构造器参数/如何使用 |
| --- | --- | --- |
| `ByteArrayInputStream |` 允许内存中的一个缓冲区作为`InputStream`使用 | 从中提取字节的缓冲区/作为一个数据源使用。通过将其同一个`FilterInputStream`对象连接,可提供一个有用的接口 |
| `StringBufferInputStream` | 将一个`String`转换成`InputStream` | 一个`String`(字符串)。基础的实现方案实际采用一个 |
| `StringBuffer`(字符串缓冲)/作为一个数据源使用。 | 通过将其同一个FilterInputStream对象连接,可提供一个有用的接口 |
| `FileInputStream` | 用于从文件读取信息 | 代表文件名的一个`String`,或者一个`File`或`FileDescriptor`对象/作为一个数据源使用。通过将其同一个`FilterInputStream`对象连接,可提供一个有用的接口 |
```
Piped-InputStream
Produces the data that’s being written to the associated PipedOutput-Stream. Implements the “piping” concept.
PipedOutputStream
As a source of data in multithreading. Connect it to a FilterInputStream object to provide a useful interface.
Sequence-InputStream
Coverts two or more InputStream objects into a single InputStream.
Two InputStream objects or an Enumeration for a container of InputStream objects.
As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
Filter-InputStream
Abstract class which is an interface for decorators that provide useful functionality to the other InputStream classes. See Table 10-3.
See Table 10-3.
See Table 10-3.
```
| 类 | 功能 | 构造器参数/如何使用 |
| --- | --- | --- |
| `PipedInputString` | 产生为相关的`PipedOutputStream`写的数据。实现了“管道化”的概念 | `PipedOutputStream`/作为一个数据源使用。通过将其同一个`FilterInputStream`对象连接,可提供一个有用的接口 |
| `SequenceInputStream` | 将两个或更多的`InputStream`对象转换成单个`InputStream`使用 | 两个`InputStream`对象或者一个`Enumeration`,用于`InputStream`对象的一个容器/作为一个数据源使用。通过将其同一个`FilterInputStream`对象连接,可提供一个有用的接口 |
| `FilterInputStream` | 对作为析构器接口使用的类进行抽象;那个析构器为其他`InputStream`类提供了有用的功能。参见表10.3 | 参见表10.3/参见表10.3 |
## 10.1.2 `OutputStream`的类型
这一类别包括的类决定了我们的输入往何处去:一个字节数组(但没有`String`;假定我们可用字节数组创建一个);一个文件;或者一个“管道”。
除此以外,`FilterOutputStream`为“析构器”类提供了一个基类,它将属性或者有用的接口同输出流连接起来。这将在以后讨论。
表10.2 `OutputStream`的类型
```
Class
Function
Constructor Arguments
How to use it
ByteArray-OutputStream
Creates a buffer in memory. All the data that you send to the stream is placed in this buffer.
Optional initial size of the buffer.
To designate the destination of your data. Connect it to a FilterOutputStream object to provide a useful interface.
File-OutputStream
For sending information to a file.
A String representing the file name, or a File or FileDescriptor object.
To designate the destination of your data. Connect it to a FilterOutputStream object to provide a useful interface.
Piped-OutputStream
Any information you write to this automatically ends up as input for the associated PipedInput-Stream. Implements the “piping” concept.
PipedInputStream
To designate the destination of your data for multithreading. Connect it to a FilterOutputStream object to provide a useful interface.
Filter-OutputStream
Abstract class which is an interface for decorators that provide useful functionality to the other OutputStream classes. See Table
10-4.
See Table 10-4.
See Table 10-4.
```
| 类 | 功能 | 构造器参数 / 如何使用 |
| --- | --- | --- | --- |
| `ByteArrayOutputStream` | 在内存中创建一个缓冲区。我们发送给流的所有数据都会置入这个缓冲区。| 可选缓冲区的初始大小 / 用于指出数据的目的地。若将其同`FilterOutputStream`对象连接到一起,可提供一个有用的接口 |
| `FileOutputStream` | 将信息发给一个文件 | 用一个String代表文件名,或选用一个`File`或`FileDescriptor`对象 / 用于指出数据的目的地。若将其同`FilterOutputStream`对象连接到一起,可提供一个有用的接口 |
| `PipedOutputStream ` | 我们写给它的任何信息都会自动成为相关的`PipedInputStream`的输出。实现了“管道化”的概念 | `PipedInputStream`/为多线程处理指出自己数据的目的地 / 将其同`FilterOutputStream`对象连接到一起,便可提供一个有用的接口
| `FilterOutputStream` | 对作为析构器接口使用的类进行抽象处理;那个析构器为其他`OutputStream`类提供了有用的功能。参见表10.4 | 参见表10.4 |
- Java 编程思想
- 写在前面的话
- 引言
- 第1章 对象入门
- 1.1 抽象的进步
- 1.2 对象的接口
- 1.3 实现方案的隐藏
- 1.4 方案的重复使用
- 1.5 继承:重新使用接口
- 1.6 多态对象的互换使用
- 1.7 对象的创建和存在时间
- 1.8 异常控制:解决错误
- 1.9 多线程
- 1.10 永久性
- 1.11 Java和因特网
- 1.12 分析和设计
- 1.13 Java还是C++
- 第2章 一切都是对象
- 2.1 用引用操纵对象
- 2.2 所有对象都必须创建
- 2.3 绝对不要清除对象
- 2.4 新建数据类型:类
- 2.5 方法、参数和返回值
- 2.6 构建Java程序
- 2.7 我们的第一个Java程序
- 2.8 注释和嵌入文档
- 2.9 编码样式
- 2.10 总结
- 2.11 练习
- 第3章 控制程序流程
- 3.1 使用Java运算符
- 3.2 执行控制
- 3.3 总结
- 3.4 练习
- 第4章 初始化和清除
- 4.1 用构造器自动初始化
- 4.2 方法重载
- 4.3 清除:收尾和垃圾收集
- 4.4 成员初始化
- 4.5 数组初始化
- 4.6 总结
- 4.7 练习
- 第5章 隐藏实现过程
- 5.1 包:库单元
- 5.2 Java访问指示符
- 5.3 接口与实现
- 5.4 类访问
- 5.5 总结
- 5.6 练习
- 第6章 类复用
- 6.1 组合的语法
- 6.2 继承的语法
- 6.3 组合与继承的结合
- 6.4 到底选择组合还是继承
- 6.5 protected
- 6.6 累积开发
- 6.7 向上转换
- 6.8 final关键字
- 6.9 初始化和类装载
- 6.10 总结
- 6.11 练习
- 第7章 多态性
- 7.1 向上转换
- 7.2 深入理解
- 7.3 覆盖与重载
- 7.4 抽象类和方法
- 7.5 接口
- 7.6 内部类
- 7.7 构造器和多态性
- 7.8 通过继承进行设计
- 7.9 总结
- 7.10 练习
- 第8章 对象的容纳
- 8.1 数组
- 8.2 集合
- 8.3 枚举器(迭代器)
- 8.4 集合的类型
- 8.5 排序
- 8.6 通用集合库
- 8.7 新集合
- 8.8 总结
- 8.9 练习
- 第9章 异常差错控制
- 9.1 基本异常
- 9.2 异常的捕获
- 9.3 标准Java异常
- 9.4 创建自己的异常
- 9.5 异常的限制
- 9.6 用finally清除
- 9.7 构造器
- 9.8 异常匹配
- 9.9 总结
- 9.10 练习
- 第10章 Java IO系统
- 10.1 输入和输出
- 10.2 增添属性和有用的接口
- 10.3 本身的缺陷:RandomAccessFile
- 10.4 File类
- 10.5 IO流的典型应用
- 10.6 StreamTokenizer
- 10.7 Java 1.1的IO流
- 10.8 压缩
- 10.9 对象序列化
- 10.10 总结
- 10.11 练习
- 第11章 运行期类型识别
- 11.1 对RTTI的需要
- 11.2 RTTI语法
- 11.3 反射:运行期类信息
- 11.4 总结
- 11.5 练习
- 第12章 传递和返回对象
- 12.1 传递引用
- 12.2 制作本地副本
- 12.3 克隆的控制
- 12.4 只读类
- 12.5 总结
- 12.6 练习
- 第13章 创建窗口和程序片
- 13.1 为何要用AWT?
- 13.2 基本程序片
- 13.3 制作按钮
- 13.4 捕获事件
- 13.5 文本字段
- 13.6 文本区域
- 13.7 标签
- 13.8 复选框
- 13.9 单选钮
- 13.10 下拉列表
- 13.11 列表框
- 13.12 布局的控制
- 13.13 action的替代品
- 13.14 程序片的局限
- 13.15 视窗化应用
- 13.16 新型AWT
- 13.17 Java 1.1用户接口API
- 13.18 可视编程和Beans
- 13.19 Swing入门
- 13.20 总结
- 13.21 练习
- 第14章 多线程
- 14.1 反应灵敏的用户界面
- 14.2 共享有限的资源
- 14.3 堵塞
- 14.4 优先级
- 14.5 回顾runnable
- 14.6 总结
- 14.7 练习
- 第15章 网络编程
- 15.1 机器的标识
- 15.2 套接字
- 15.3 服务多个客户
- 15.4 数据报
- 15.5 一个Web应用
- 15.6 Java与CGI的沟通
- 15.7 用JDBC连接数据库
- 15.8 远程方法
- 15.9 总结
- 15.10 练习
- 第16章 设计模式
- 16.1 模式的概念
- 16.2 观察器模式
- 16.3 模拟垃圾回收站
- 16.4 改进设计
- 16.5 抽象的应用
- 16.6 多重分发
- 16.7 访问器模式
- 16.8 RTTI真的有害吗
- 16.9 总结
- 16.10 练习
- 第17章 项目
- 17.1 文字处理
- 17.2 方法查找工具
- 17.3 复杂性理论
- 17.4 总结
- 17.5 练习
- 附录A 使用非JAVA代码
- 附录B 对比C++和Java
- 附录C Java编程规则
- 附录D 性能
- 附录E 关于垃圾收集的一些话
- 附录F 推荐读物