`

适配器模式和InputStreamReader/OutputStreamWriter

    博客分类:
  • java
 
阅读更多

java.io包中的字符流(下)—— 适配器模式和InputStreamReader/OutputStreamWriter

 

摘自:http://www.molotang.com/articles/782.html

在前一篇文章中,我们已经对Java IO中的Reader和Writer做了介绍,并对其中一些实现的使用做了分析和整理。除了上篇文章中提到的那些字符流IO类,Reader和Writer还有InputStreamReader、FileReader和OutputStreamWriter、FileWriter这样4个实现的子类,而他们和字节流之间的关系采用了适配器这种设计模式,我们接下来就对适配器模式和这四个类详细介绍下。

0. 适配器模式 ( Adapter )

我们先来说说JavaIO中用到的适配器模式。谈到设计模式,我们就不得不提GoF经典的著作《Design Patterns: Elements of Reusable Object-Oriented Software》(《设计模式》)。在这本书中,作者将提到的23种设计模式根据应用场景考虑,分为3大类:

  • 构建型设计模式。主要描述几种不同场景下的对象生成的方式。
  • 结构型模式。描述在面向对象设计中,类和对象的几种结构关系。
  • 行为型设计模式。主要是考虑在有Action进来时,信息的传递和行为的执行。

我们这里提到的适配器模式属于结构型设计模式,而Java的字符流IO类Reader/Writer和字节流IO类之间的关系正式以这个适配器模式来设计的。下面我们简要来看下。

适配器模式通常有2种实现方式:一种是类适配,也就是通过类似多继承的形式;而另外一种就是对象适配,通常是通过引用潜入来实现的。我们可以看两张比较直观的类结构图说明,这样就不需要多说明什么了。

适配器模式的类适配方式

适配器模式的类适配方式

当适配的对象调用Request()的方法时,适配器实现类会调用实际父类的SpecificRequest()方法来完成,从而实现了适配。

下面再来看对象适配实现形式。

适配器模式的对象适配方式

适配器模式的对象适配方式

当适配的对象调用Request()的方法时,适配器实现类会调用实际包装嵌入的引用对象的SpecificRequest()方法来完成,从而实现了适配。

最后,在简要说下适配器模式和装饰模式以及代理模式的关系。

  • 装饰模式 ( Decorator )。前面也提到过,是通过对一个已有对象的进一步分装来实现功能上的扩展。这个相对于类扩展继承更为动态化,是基于已有对象而非类的扩展。
  • 代理模式 ( Proxy )。也是通过对一个对象的“封装”,“屏蔽”掉client请求对真实原始对象的直接调用,来增加做访问控制方面的处理逻辑。

单纯从类和对象结构上来看,装饰模式、代理模式和适配器模式(尤其是对象的实现方式)大有相似之处。但之所以这几个是不同的设计模式,是我们设计考虑的出发点和细节不同,从描述中也可以看得出来。

适配器模式偏重的是适配,即实现要适配的接口功能。装饰模式偏重的是对已有对象的功能扩展。而代理模式则偏重的是访问逻辑的控制,因此通常这个代理的构建过程是不直接由client控制的。

1. InputStreamReader和OutputStreamWriter

对于字符流IO类的使用,使用FileReader和FileWriter进行文件读写操作是比较经常用到的。而java.io包中的FileReader和FileWriter类分别继承自InputStreamReader和OutputStreamWriter,而且实际上FileReader和FileWriter的主要实现逻辑都在父类InputStreamReader和OutputStreamWriter中,我们先来看下这两个父类。

InputStreamReader和OutputStreamWriter分别继承自java.io包中的Reader和Writer,对他们中的抽象的未实现的方法给出实现。如:

1
2
3
public int read(char cbuf[], int offset, int length) throws IOException {
    return sd.read(cbuf, offset, length);
}

如上代码中的sd(StreamDecoder类对象),在Sun的JDK实现中,实际的方法实现是对sun.nio.cs.StreamDecoder类和sun.nio.cs.StreamEncoder类的同名方法的调用封装。我们可以通过这样两张类结构关系图看下。

字节流到字符流解码的相关类结构关系

字节流到字符流解码的相关类结构关系

我们再来看下OutputStreamWriter相关的类结构关系:

字符流到字节流编码相关类结构关系

字符流到字节流编码相关类结构关系

我们看到这样几点:

  • InputStreamReader和OutputStreamWriter实际上是对同样继承了Reader和Writer的StreamDecoder和StreamEncoder的封装
  • StreamDecoder和StreamEncoder不是Java SE API中的内容,是Sun JDK给出的自身实现。但我们知道他们对构造方法中的字节流类(InputStream和OutputStream)参数和字符集类(Charset)进行了封装,并通过此二者进行了字节流和字符流之间的编码解码转换

从表层来看,InputStreamReader和OutputStreamWriter做了InputStream/OutputStream字节流类到Reader/Writer之间的转换。而从如上Sun JDK中的实现类关系结构中可以看出,是StreamDecoder和StreamEncoder的设计实现在实际上采用了适配器模式。

下面我们再来看看子类FileReader和FileWriter。

2. FileReader和FileWriter

上文多次提到了这两个类,他们分别继承于InputStreamReader和OutputStreamWriter。更重要的是,他们的read和write逻辑,甚至编码解码都是采用父类的。

打开Sun JDK中这两个类的源码实现可以看到,这两个类本身的实现只有几个重载的构造方法。在这几个构造方法中实际所做的事情就是将各类参数最终转为java.io包中的FileInputStream和FileOutputStream字节流类,传给父类,即InputStreamReader和OutputStreamWriter的构造方法。

除此之外,这两个类中没有给出其他的任何实现。

分享到:
评论

相关推荐

    [结构型模式] 适配器模式的理解

    适配器模式在很多开源框架和库中都有体现,例如Java的InputStreamReader和OutputStreamWriter,它们起到了字符流和字节流之间的适配作用。在Android开发中,ListView和RecyclerView的Adapter也是适配器模式的典型...

    JAVA设计模式之适配器模式.docx

    - JDK的IO模块中,`InputStreamReader`和`OutputStreamWriter`是适配器模式的实例,它们将字节流(`InputStream`/`OutputStream`)适配为字符流(`Reader`/`Writer`)。 - MyBatis的源码中,日志模块使用对象适配器...

    适配器模式

    又如,Java中的InputStreamReader和OutputStreamWriter作为字符流和字节流之间的适配器,允许两者之间的转换。 适配器模式有以下优点: - 提高了类的复用性,通过适配器可以重用已有的类,而无需修改原有代码。 - ...

    Java-从Decorator,Adapter模式看Java/IO

    Java的IO库是一个复杂而强大的系统,其设计思想和实现方式体现了多种设计模式,包括Decorator(装饰者)模式和Adapter(适配器)模式。本文将深入探讨这两个模式在Java/IO中的应用,并通过实例解释它们如何使得Java...

    北京恒信启华信息技术有限公司Java笔试题

    单例模式、工厂模式、抽象工厂模式、建造者模式、装饰器模式、代理模式、适配器模式、桥接模式、组合模式、享元模式、职责链模式、命令模式、解释器模式、状态模式、策略模式、模板方法模式、访问者模式等23种经典...

    java面试知识点

    6. **IO流**:字节流(InputStream/OutputStream)和字符流(Reader/Writer)的区别,缓冲流(BufferedInputStream/BufferedReader)的使用,转换流(InputStreamReader/OutputStreamWriter),以及File类的操作。...

    北大软件所老师Java高级技术讲课PPT

    3. **设计模式.pdf**和**设计模式2.pdf**:这两部分通常涵盖了常见的设计模式,如单例模式、工厂模式(简单工厂、工厂方法、抽象工厂)、建造者模式、装饰器模式、适配器模式、代理模式、观察者模式、职责链模式、...

    2012java面试题.2

    6. **IO流**:Java的输入输出流体系包括字节流(InputStream/OutputStream)和字符流(Reader/Writer),以及其缓冲流(BufferedInputStream/BufferedReader)和转换流(InputStreamReader/OutputStreamWriter)。...

    面试题大全

    - 转换流(InputStreamReader/OutputStreamWriter)的作用 - 文件流(FileInputStream/FileOutputStream)及缓冲流(BufferedReader/BufferedWriter) - NIO(New Input/Output)的使用 7. 网络编程: - Socket...

    adapter:关于适配器模式的一小时研讨会的临时项目

    - 在Java IO流中,`InputStreamReader`和`OutputStreamWriter`就是适配器的例子,它们分别将字节流转换为字符流,实现了不同数据类型的适配。 - JDBC驱动程序也是一个适配器的例子,它提供了标准的API,使得不同的...

    张孝祥正在整理Java就业面试题大全

    - 常见设计模式:了解单例、工厂、观察者、装饰者、适配器等23种设计模式的实现和应用。 这份面试题大全深入浅出地涵盖了Java程序员应知应会的知识点,对于即将参加Java就业面试的开发者来说,是一份非常有价值的...

    最全的java面试题

    - 转换流:InputStreamReader/OutputStreamWriter用于字节流和字符流之间的转换。 - 缓冲流:提高读写性能。 - NIO(New IO):非阻塞I/O,提供选择器和通道功能。 7. **反射** - 类加载:ClassLoader的工作...

    北京锋威通成技术有限公司Java笔试题

    6. **IO流**:熟悉字节流和字符流,了解InputStream、OutputStream、Reader、Writer及其子类的用法,以及缓冲流(BufferedInputStream/Reader)和转换流(InputStreamReader/OutputStreamWriter)。还要理解文件操作...

    Java常见技术面试题程序员面试合集资料

    - 转换流(InputStreamReader/OutputStreamWriter)的作用。 - 文件操作:File类的常用方法,以及FileInputStream、FileOutputStream等的使用。 8. **反射**: - 如何通过Class对象获取类的信息。 - 动态调用...

    程序员面试题_Java

    - 转换流:InputStreamReader/OutputStreamWriter在字节流和字符流之间的转换。 7. **网络编程**: - Socket编程:TCP与UDP的区别,Socket与ServerSocket的用法。 - URL和URLConnection:网络资源的访问和下载。...

    Java南开上机题(全)

    包括InputStream/OutputStream、Reader/Writer,以及缓冲流(BufferedInputStream/BufferedOutputStream/BufferedReader/BufferedWriter)和转换流(InputStreamReader/OutputStreamWriter)。 6. **集合框架**:...

    java面试——深圳-乐信-Java高级.zip

    - 转换流(InputStreamReader/OutputStreamWriter)和字符集编码。 - NIO(New IO)的特性,通道和缓冲区。 10. **Spring框架及其实现原理**: - DI(依赖注入)和AOP(面向切面编程)的概念。 - Bean的生命...

    Java 面试题经典 77 问!.zip

    - 转换流(InputStreamReader/OutputStreamWriter)和对象序列化。 8. **网络编程** - Socket编程基础,TCP和UDP的区别。 - URL和URLConnection的使用。 9. **反射** - 反射的基本概念,如何通过Class对象操作...

    JAVA面试题

    - 转换流(InputStreamReader/OutputStreamWriter)在字节流和字符流之间转换。 10. **网络编程** - Socket编程:ServerSocket和Socket类实现客户端/服务器通信。 - URL和URLConnection类用于访问网络资源。 11...

    JavaEE面试宝典

    - **适配器模式**:例如,`InputStreamReader` 和 `OutputStreamWriter` 就是适配器模式的应用实例,它们将字节流转换为字符流。 - `InputStreamReader`:将 `InputStream` 转换成 `Reader`。 - `...

Global site tag (gtag.js) - Google Analytics