32.JAVA编程思想——JAVA IO添加属性和接口

32.JAVA编程思想——JAVA IO添加属性和接口

增添属性和有用的接口

利用层次化对象动态和透明地添加单个对象的能力的做法叫作“装饰器”(Decorator)方案。装饰器方案规定封装于初始化对象中的所有对象都拥有相同的接口,以便利用装饰器的“透明”性质——我们将相同的消息发给一个对象,无论它是否已被“装饰”。这正是在Java

IO库里存在“过滤器”(Filter)类的原因:抽象的“过滤器”类是所有装饰器的基础类(装饰器必须拥有与它装饰的那个对象相同的接口,但装饰器亦可对接口作出扩展,这种情况见诸于几个特殊的“过滤器”类中)。

子类处理要求大量子类对每种可能的组合提供支持时,便经常会用到装饰器——由于组合形式太多,造成子类处理变得不切实际。Java IO库要求许多不同的特性组合方案,这正是装饰器方案显得特别有用的原因。

但是,装饰器方案也有自己的一个缺点。在我们写一个程序的时候,装饰器为我们提供了大得多的灵活性(因为可以方便地混合与匹配属性),但它们也使自己的代码变得更加复杂。原因在于Java IO 库操作不便,我们必须创建许多类——“核心”IO类型加上所有装饰器——才能得到自己希望的单个IO 对象。

FilterInputStream和FilterOutputStream(这两个名字不十分直观)提供了相应的装饰器接口,用于控制一个特定的输入流(InputStream)或者输出流(OutputStream)。它们分别是从 InputStream和OutputStream衍生出来的。此外,它们都属于抽象类,在理论上为我们与一个流的不同通信手段都提供了一个通用的接口。事实上,FilterInputStream和 FilterOutputStream 只是简单地模仿了自己的基础类,它们是一个装饰器的基本要求。

l  通过FilterInputStream 从 InputStream 里读入数据

FilterInputStream类要完成两件全然不同的事情。其中,DataInputStream 允许我们读取不同的基本类型数据以及String 对象(所有方法都以“read”开头,比如 readByte(),readFloat()等等)。伴随对应的DataOutputStream,我们可通过数据“流”将基本类型的数据从一个地方搬到另一个地方。若读取块内的数据,并自己进行解析,就不需要用到DataInputStream。但在其他许多情况下,我们一般都想用它对自己读入的数据进行自动格式化。

剩下的类用于修改InputStream的内部行为方式:是否进行缓冲,是否跟踪自己读入的数据行,以及是否能够推回一个字符等等。后两种类看起来特别象提供对构建一个编译器的支持(换言之,添加它们为了支持Java 编译器的构建),所以在常规编程中一般都用不着它们。也许几乎每次都要缓冲自己的输入,无论连接的是哪个IO设备。所以 IO 库最明智的做法就是将未缓冲输入作为一种特殊情况处理,同时将缓冲输入接纳为标准做法。

DataInputStream 与 DataOutputStream联合使用,使自己能以机动方式读取一个流中的基本数据类型(int,char,long 等等) InputStream/包含了一个完整的接口,以便读取基本数据类型BufferedInputStream 避免每次想要更多数据时都进行物理性的读取,告诉它“请先在缓冲区里找”InputStream,没有可选的缓冲区大小/本身并不能提供一个接口,只是发出使用缓冲区的要求。要求同一个接口对象连接到一起LineNumberInputStream 跟踪输入流中的行号;可调用 getLineNumber()以及setLineNumber(int) 只是添加对数据行编号的能力,所以可能需要同一个真正的接口对象连接PushbackInputStream 有一个字节的后推缓冲区,以便后推读入的上一个字符 InputStream/通常由编译器在扫描器中使用,因为 Java 编译器需要它。一般不在自己的代码中使用

l  通过FilterOutputStream 向 OutputStream 里写入数据

与DataInputStream 对应的是DataOutputStream,后者对各个基本数据类型以及String对象进行格式化,并将其置入一个数据“流”中,以便任何机器上的 DataInputStream都能正常地读取它们。所有方法都以“wirte”开头,例如 writeByte(),writeFloat()等等。

若想进行一些真正的格式化输出,比如输出到控制台,请使用 PrintStream。利用它可以打印出所有基本数据类型以及 String对象,并可采用一种易于查看的格式。这与DataOutputStream 正好相反,后者的目标是将那些数据置入一个数据流中,以便DataInputStream 能够方便地重新构造它们。System.out 静态对象是一个PrintStream。

PrintStream内两个重要的方法是 print()和println()。它们已进行了覆盖处理,可打印出所有数据类型。

print()和 println()之间的差异是后者在操作完毕后会自动添加一个新行。

BufferedOutputStream属于一种“修改器”,用于指示数据流使用缓冲技术,使自己不必每次都向流内物理性地写入数据。通常都应将它应用于文件处理和控制器IO。

DataOutputStream 与DataInputStream配合使用,以便采用方便的形式将基本数据类型(int,char,long等)写入一个数据流 OutputStream/包含了完整接口,以便我们写入基本数据类型PrintStream 用于产生格式化输出。DataOutputStream 控制的是数据的“存储”,而PrintStream 控制的是“显示” OutputStream,可选一个布尔参数,指示缓冲区是否与每个新行一同刷新/对于自己的

OutputStream对象,应该用“final”将其封闭在内。可能经常都要用到它BufferedOutputStream 用它避免每次发出数据的时候都要进行物理性的写入,要求它“请先在缓冲区里找”。可调用flush(),对缓冲区进行刷新 OutputStream,可选缓冲区大小/本身并不能提供一个接口,只是发出使用缓冲区的要求。需要同一个接口对象连接到一起

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值