JAVA编程思想——JAVAIO添加属性和接口
增添属性和有用的接口
利用层次化对象动态和透明地添加单个对象的能力的做法叫作“装饰器”方案。装饰器方案规定封装于初始化对象中的所有对象都拥有相同的接口,以便利用装饰器的“透明”性质——我们将相同的消息发给一个对象,无论它是否已被“装饰”。这正是在Java
IO库里存在“过滤器”类的原因:抽象的“过滤器”类是所有装饰器的基础类。
子类处理要求大量子类对每种可能的组合提供支持时,便经常会用到装饰器——由于组合形式太多,造成子类处理变得不切实际。JavaIO库要求许多不同的特性组合方案,这正是装饰器方案显得特别有用的原因。
装饰器方案也有自己的一个缺点。在我们写一个程序的时候,装饰器为我们提供了大得多的灵活性,但它们也使自己的代码变得更加复杂。原因在于JavaIO库操作不便,我们必须创建许多类——“核心”IO类型加上所有装饰器——才能得到自己希望的单个IO对象。
FilterInputStream和FilterOutputStream提供了相应的装饰器接口,用于控制一个特定的输入流或者输出流。它们分别是从InputStream和OutputStream衍生出来的。此外,它们都属于抽象类,在理论上为我们与一个流的不同通信手段都提供了一个通用的接口。事实上,FilterInputStream和FilterOutputStream只是简单地模仿了自己的基础类,它们是一个装饰器的基本要求。
l通过FilterInputStream从InputStream里读入数据
FilterInputStream类要完成两件全然不同的事情。其中,DataInputStream允许我们读取不同的基本类型数据以及String对象。伴随对应的DataOutputStream,我们可通过数据“流”将基本类型的数据从一个地方搬到另一个地方。若读取块内的数据,并自己进行解析,就不需要用到DataInputStream。但在其他许多情况下,我们一般都想用它对自己读入的数据进行自动格式化。
剩下的类用于修改InputStream的内部行为方式:是否进行缓冲,是否跟踪自己读入的数据行,以及是否能够推回一个字符等等。后两种类看起来特别象提供对构建一个编译器的支持,所以在常规编程中一般都用不着它们。也许几乎每次都要缓冲自己的输入,无论连接的是哪个IO设备。所以IO库最明智的做法就是将未缓冲输入作为一种特殊情况处理,同时将缓冲输入接纳为标准做法。
DataInputStream与DataOutputStream联合使用,使自己能以机动方式读取一个流中的基本数据类型InputStream/包含了一个完整的接口,以便读取基本数据类型BufferedInputStream避免每次想要更多数据时都进行物理性的读取,告诉它“请先在缓冲区里找”InputStream,没有可选的缓冲区大小/本身并不能提供一个接口,只是发出使用缓冲区的要求。要求同一个接口对象连接到一起LineNumberInputStream跟踪输入流中的行号;可调用getLineNumber()以及setLineNumber(int)只是添加对数据行编号的能力,所以可能需要同一个真正的接口对象连接PushbackInputStream有一个字节的后推缓冲区,以便后推读入的上一个字符InputStream/通常由编译器在扫描器中使用,因为Java编译器需要它。一般不在自己的代码中使用
l通过FilterOutputStream向OutputStream里写入数据
与DataInputStream对应的是DataOutputStream,后者对各个基本数据类型以及String对象进行格式化,并将其置入一个数据“流”中,以便任何机器上的DataInputStream都能正常地读取它们。所有方法都以“wirte”开头,例如writeByte(),writeFloat()等等。
若想进行一些真正的格式化输出,比如输出到控制台,请使用PrintStream。利用它可以打印出所有基本数据类型以及String对象,并可采用一种易于查看的格式。这与DataOutputStream正好相反,后者的目标是将那些数据置入一个数据流中,以便DataInputStream能够方便地重新构造它们。Systeout静态对象是一个PrintStream。
PrintStream内两个重要的方法是print()和println()。它们已进行了覆盖处理,可打印出所有数据类型。
print()和println()之间的差异是后者在操作完毕后会自动添加一个新行。
BufferedOutputStream属于一种“修改器”,用于指示数据流使用缓冲技术,使自己不必每次都向流内物理性地写入数据。通常都应将它应用于文件处理和控制器IO。
DataOutputStream与DataInputStream配合使用,以便采用方便的形式将基本数据类型写入一个数据流OutputStream/包含了完整接口,以便我们写入基本数据类型PrintStream用于产生格式化输出。DataOutputStream控制的是数据的“存储”,而PrintStream控制的是“显示”OutputStream,可选一个布尔参数,指示缓冲区是否与每个新行一同刷新/对于自己的
OutputStream对象,应该用“final”将其封闭在内。可能经常都要用到它BufferedOutputStream用它避免每次发出数据的时候都要进行物理性的写入,要求它“请先在缓冲区里找”。可调用flush(),对缓冲区进行刷新OutputStream,可选缓冲区大小/本身并不能提供一个接口,只是发出使用缓冲区的要求。需要同一个接口对象连接到一起
文章为作者独立观点,不代表观点