`

适配器模式和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源码分析_动力节点Java学院整理

    本文通过示例代码给大家解析了Java中的InputStreamReader和OutputStreamWriter知识,需要的的朋友参考下吧

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

    适配器模式在源码中的应用: (1)JDK源码的IO模块用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。 (2)mybatis源码日志模块用到对象适配器模式。

    IO基础(字符流)

    IO基础(字符流) 文章目录IO基础(字符流)一、字符流二、常用的字符流类的继承关系三、字符流 FileReader 和 FileWriter四、字符缓冲流 BufferedReader 和...一、字符流 字符流类都是以Reader/...

    (超赞)JAVA精华之--深入JAVA API

    1.3.9 字符流 InputStreamReader/OutputStreamWriter 1.3.10 随机存取文件 RandomAccessFile 1.3.11 小结 1.4 java中的一些常用词汇 1.5 J2SE学习中的30个基本概念 1.6 Java线程 1.7 Java 5.0多线程编程 1.8 Java ...

    JAVA SE学习精华集锦

    1.3.9 字符流 InputStreamReader/OutputStreamWriter 55 1.3.10 随机存取文件 RandomAccessFile 56 1.3.11 小结 56 1.4 java中的一些常用词汇 56 1.5 J2SE学习中的30个基本概念 58 1.6 Java线程 60 1.7 Java 5.0多...

    Java I/O 第二版

    OReilly.Java.I.O.2nd.Edition.May.2006 Java的io包主要包括: 1. 两种流:字节流(byte Stream)和字符流(character stream),这...3. 一个桥梁:将字节流转变为字符流的InputStreamReader和OutputStreamWriter。

    Java字符流与字节流区别

    Java 流在处理上分为字符流和字节流。字符流处理的单元为 2 ...而类 InputStreamReader 和 OutputStreamWriter 处理字符流和字节流的转换。字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高。

    高阶JAVA篇-深入解读字符集.pptx.pptx

    Java字符编码基础 Java字符编码是处理文本信息的基础,它规定了...Java提供了丰富的API用于字符编码的处理,如Charset类可以获取系统默认的字符编码,InputStreamReader和OutputStreamWriter可以进行字符编码的转换。

    拒绝枯燥乏味,手写跨进程、跨网络聊天程序,Socket+Swing实现简易通信

    结合 1.Properties、FileReader、File和配置文件 2.BufferedReader/Writer、InputStreamReader、OutputStreamWriter 3.Soket、 4.ServerSocket、 5.JWT、 6.Swing 跨进程通信、网络聊天

    JavaIo流分析图

    分析Java常用IO流,包括InputStream、OutputStream、FileInputStream、FileOutputStream、BufferedInputStream、BufferedOutputStream、Reader、Writer、InputStreamReader、OutputStreamWriter、FileReader、...

    Java设计模式

    ● java.io.InputStreamReader(InputStream) ● java.io.OutputStreamWriter(OutputStream) ● javax.xml.bind.annotation.adapters.XmlAdapter#marshal() ● javax.xml.bind.annotation.adapters.XmlAdapter#...

    一篇文章带你了解IO流

    流一、流的概念二、流的分类三、 字节流3.1 字节流的父类(抽象类):3.2 所有方法...6.2 主要方法ReaderWriter6.3 字符节点流`FileWriter `和`FileReader`6.3 字符处理流——缓冲流`InputStreamReader/Out

    InputStreamReader和BufferedReader用法及实例讲解

    主要介绍了InputStreamReader和BufferedReader用法及实例讲解的相关资料,需要的朋友可以参考下

    JavaIO流精讲上

    课程内容主要有:File类概述、File类功能讲解、JAVA IO流概述、字节流、字符流、缓冲流、InputStream、OutputStream、Reader、Writer、FileInputStream、FileOutputStream、InputStreamReader、OutputStreamWriter、...

    IO流各个类的使用方法

    介绍了,下面这些类的具体使用方法,非常详细,值得一看 File FileFilter RandomAccessFile ...InputStreamReader OutputStreamWriter BufferedReader BufferedWriter /PrintWriter FileReader FileWriter

    java IO章节的总结

    第三,是否需要转换流:InputStreamReader, OutputStreamWriter? 第四,数据来源(去向)是什么:文件?内存?网络? 首先是字节流: InputStream的实现类(System.in返回一个输入流): 1)ByteArrayInputStream...

    Android中文件读写(输入流和输出流)操作小结

    1. Android中文件读写的原理: (1)....字节流转换成字符流可以用InputStreamReader,OutputStreamWriter。 一般我们在使用的时候通常用字节流。 3. 文件读写的步骤: (1).首先建立通道。 (2).然后建

    java io 类 小结 代码

    简洁分类 代码直接使用 ...InputStreamReader OutputStreamWriter BufferedReader BufferedWriter PrintWriter DataOutputStream DataInputStream ObjectOutputStream ObjectInputStream Scanner

    JAVA基础课程讲义

    InputStreamReader和OutputStreamWriter 161 JAVA对象的序列化和反序列化 161 为什么需要序列化和反序列化 161 对象的序列化主要有两种用途 161 序列化涉及的类和接口 162 序列化/反序列化的步骤和实例 162 综合的...

Global site tag (gtag.js) - Google Analytics