36.JAVA编程思想——JAVA IO Java 1.1 的 IO 流

36.JAVA编程思想——JAVA IO Java 1.1 的 IO 流

是否存在IO 流的另一种设计方案,并可能要求更大的代码量。还有人能提出一种更古怪的设计吗?事实上,Java 1.1 对IO 流库进行了一些重大的改进。看到 Reader和Writer 类时,大多数人的第一个印象就是它们用来替换原来的InputStream 和OutputStream类。但实情并非如此。尽管不建议使用原始数据流库的某些功能(如使用它们,会从编译器收到一条警告消息),但原来的数据流依然得到了保留,以便维持向后兼容,而且:

(1) 在老式层次结构里加入了新类,所以Sun 公司明显不会放弃老式数据流。

(2) 在许多情况下,我们需要与新结构中的类联合使用老结构中的类。为达到这个目的,需要使用一些“桥”类:InputStreamReader将一个 InputStream转换成 Reader,OutputStreamWriter 将一个OutputStream转换成 Writer。

所以与原来的IO 流库相比,经常都要对新IO流进行层次更多的封装。同样地,这也属于装饰器方案的一个缺点——需要为额外的灵活性付出代价。

之所以在Java 1.1 里添加了Reader 和 Writer层次,最重要的原因便是国际化的需求。老式 IO流层次结构只支持8 位字节流,不能很好地控制16 位Unicode 字符。由于Unicode 主要面向的是国际化支持(Java 内含的char 是16 位的Unicode),所以添加了Reader 和 Writer层次,以提供对所有IO 操作中的Unicode 的支持。除此之外,新库也对速度进行了优化,可比旧库更快地运行。

数据的发起与接收

Java 1.0 的几乎所有 IO流类都有对应的Java 1.1 类,用于提供内建的Unicode管理。似乎最容易的事情就是“全部使用新类,再也不要用旧的”,但实际情况并没有这么简单。有些时候,由于受到库设计的一些限制,我们不得不使用Java 1.0 的 IO流类。特别要指出的是,在旧流库的基础上新加了 java.util.zip 库,它们依赖旧的流组件。所以最明智的做法是“尝试性”地使用 Reader和 Writer类。若代码不能通过编译,便知道必须换回老式库。

修改数据流的行为

在Java 1.0中,数据流通过 FilterInputStream和FilterOutputStream 的“装饰器”(Decorator)子类适应特定的需求。Java 1.1 的 IO流沿用了这一思想,但没有继续采用所有装饰器都从相同“filter”(过滤器)基础类中衍生这一做法。若通过观察类的层次结构来理解它,这可能令人出现少许的困惑。在下面这张表格中,对应关系比上一张表要粗糙一些。之所以会出现这个差别,是由类的组织造成的:尽管BufferedOutputStream是 FilterOutputStream 的一个子类,但是BufferedWriter 并不是FilterWriter的子类(对后者来说,尽管它是一个抽象类,但没有自己的子类或者近似子类的东西,也没有一个“占位符”可用,所以不必费心地寻找)。然而,两个类的接口是非常相似的,而且不管在什么情况下,显然应该尽可能地使用新版本,而不应考虑旧版本(也就是说,除非在一些类中必须生成一个Stream,不可生成 Reader或者Writer)。

过滤器:Java 1.0 类对应的Java 1.1 类

FilterInputStream FilterReader

FilterOutputStream FilterWriter(没有子类的抽象类)

BufferedInputStream BufferedReader(也有readLine())

BufferedOutputStream BufferedWriter

DataInputStream 使用DataInputStream(除非要使用readLine(),那时需要使用一个 BufferedReader)

PrintStream PrintWriter

LineNumberInputStream LineNumberReader

StreamTokenizer StreamTokenizer(用构建器取代Reader)

PushBackInputStream PushBackReader

有一条规律是显然的:若想使用readLine(),就不要再用一个DataInputStream 来实现(否则会在编译期得到一条出错消息),而应使用一个 BufferedReader。但除这种情况以外,DataInputStream 仍是Java 1.1IO库的“首选”成员。

为了将向PrintWriter 的过渡变得更加自然,它提供了能采用任何OutputStream对象的构建器。PrintWriter提供的格式化支持没有 PrintStream 那么多;但接口几乎是相同的。

未改变的类

显然,Java 库的设计人员觉得以前的一些类毫无问题,所以没有对它们作任何修改,可象以前那样继续使用它们:

没有对应Java 1.1 类的Java 1.0 类

DataOutputStream

File

RandomAccessFile

SequenceInputStream

特别未加改动的是DataOutputStream,所以为了用一种可转移的格式保存和获取数据,必须沿用InputStream和 OutputStream层次结构。

重导向标准 IO

Java 1.1 在System 类中添加了特殊的方法,允许我们重新定向标准输入、输出以及错误 IO流。此时要用到下述简单的静态方法调用:

setIn(InputStream)

setOut(PrintStream)

setErr(PrintStream)

如果突然要在屏幕上生成大量输出,而且滚动的速度快于人们的阅读速度,输出的重定向就显得特别有用。在一个命令行程序中,如果想重复测试一个特定的用户输入序列,输入的重定向也显得特别有价值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值