【Java-IO】- 1.I/O系统与装饰者模式

1.流类

a.流的概念

Java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输人:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文件或相连的网络。流是处理输入/输出的一个洁净的万法,例如它不需要代码理解键盘和网络的不同。Java中流的实现是在java.io包定义的类层次结构内部的。

b.输入/输出流的概念

1.输入输出时,数据在通信通道中流动。所谓数据流(stream)指的是所有的数据通信通道中,数据的起点和终点。信息的通道就是一个数据流。只要数据从一个地方流到另一个地方,这种数据的流动的通道就可以称为数据流。

2.输入输出是相对于程序来说的,程序在使用数据时所扮演的角色有两个,一个是源,一个是目的。若程序是数据流的源,即数据的提供方,数据流对这个程序来说就是输出数据流(数据的流出)。若程序是数据的接收方即数据流的终点,这个数据流对程序来说就是输入数据流(数据流向程序)

c.Java中的流

  • 在java.io包中提供了60多个类(流)。

  • 从功能上分为两大类:输入流和输出流。

  • 从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。

  • 字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer

字符流和字节流

Java2定义了两种类型的流:字节流和字符流。字节流(byte stream)为处理字节的输人和输出提供了方便的方法。例如使用字节流读取或写人二进制数据。字符流(character stream)为字符的输入和输出处理提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效

Java1中是没有字符流的,因为所有的输入输出都是以字节为单位的,Java1.1中加入了字符流。

需要声明的是:在最底层,所有的输入输出都是以字节的形式进行。基于字符的流的处理只是为了提供字符处理有效地方法。

d.流的分类

  • 节点流:从特定地方读写的流类。例如:磁盘或内存的某一区域。
  • 过滤流:使用节点流作为输入或输出。过滤流使用一个已经存在的输入或输出流链接而创建。
    在这里插入图片描述

e.java.io中InputStream的类层次

在这里插入图片描述

InputStream

InputStream中包含一套字节输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的InputStream子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输人方法来实现对相应外设的输入操作。

InputStream类子类对象自然也继承了InputStream类的方法。常用的方法有:读数据的方法read(),获取输入流字节数的方法available(),定位输入位置指针的方法skip()、reset()、mark()等。

f.java.io中OutputStream的类层次

在这里插入图片描述

InputStream与OutputStream链接文件的方式

在这里插入图片描述

g.过滤流

  • 在InputStream类和OutputStream类子类中FilterInputStream和FilterOutputStream过滤流抽象类又派生出DatalnputStream和DataOutputStream数据输入输出流类等子类。

h.java.io中Reader的类层次

在这里插入图片描述

i.java.io中Write的类层次

在这里插入图片描述

2.Java IO库的基本设计模式

  • Java的I/O库提供了一个称做链接的机制,可以将一个流与另一个流首尾相接,形成一个流管道的链接。这种机制实际上是一种被称为Decorator(装饰)设计模式的应用。
  • 通过流的链接,可以动态的增加流的功能,而这种功能的增加是通过组合一些流的基本功能而动态获取的。
  • 我们要获取一个I/O对象,往往需要产生多个I/O对象,这也是JavaI/O库不太容易掌握的原因,但在I/O库中Decorator模式的运用,给我们提供了实现上的灵活性。

3.装饰者模式(Decorator)

装饰模式又称包装(Wrapper)模式

  • 装饰模式是对客户端透明的方式的扩展对象的功能,是继承关系的替代方案

  • 装饰模式以对客户端透明的方式给一个对象附上更多的责任。换言之客户端不会感觉对象在装饰前后的不同。

  • 装饰模式可以在不创建更多子类的情况下,将对象的功能加以扩展

  • 装饰模式是不必在改变原有类文件和使用继承的情况下,动态的扩展一个类的功能。它提供创建一个包装对象来包裹真实的对象

a.装饰模式的角色

  • 抽象构建角色(Component):给一个抽象接口,以规范准备接收附加责任的对象
  • 具体构建对象(Concrete Component):定义一个接收附加责任的类
  • 装饰角色(Decorator):持有一个构件(Component)对象引用,并定义一个与抽象构建接口一致的接口。
  • 具体装饰角色(Concete Decorator):负责给构件对象加上附加责任

b.装饰者模式的特点

  • 装饰对象和真实对象有相同的接口 。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。

  • 装饰对象包含一个真实对象的引用(reference)

  • 装饰对象接收所有来自客户端的请求。它把这些请求转发给真实的对象。

  • 饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

c.编码实现

//顶层接口相当于Stream
public interface Component {
    void doSomething();
}


public class ConcrataConponent implements Component {
    public void doSomething() {
        System.out.println("功能1");
    }
}


public class Decorator implements Component {

    private Component component;

    public Decorator(Component component){
        this.component = component;
    }

    public void doSomething() {
        component.doSomething();
    }
}

public class ConcrataDecorator1 extends Decorator {

    public ConcrataDecorator1(Component component) {
        super(component);
    }

    //对已有对象包装,并且添加部分功能
    @Override
    public void doSomething() {
        super.doSomething();
        this.doAnotherthing();
    }

    private void doAnotherthing() {
        System.out.println("功能2");
    }
}

public class Client {
    public static void main(String[] args) {
    //实现了对对象的装饰
        Component component = new ConcrataDecorator1(new ConcrataConponent());
        component.doSomething();
    }
}

//输出
功能1
功能2

e.装饰者模式与继承的对比

装饰模式
  • 用来扩展特定对象的功能

  • 不需要子类

  • 动态

  • 运行时分配职责

  • 防止由于子类而导致的复杂和混乱

  • 更多的灵活性

  • 对一个给定的对象…回过可熊有不同的装饰对象,客户端可以通过它需要选择合适的装饰对象发送消息。

继承
  • 用来扩展一类对象的功能
  • 需要子类
  • 静态
  • 编译时分派职责
  • 导致很多子类产生
  • 缺乏灵活性

f.何时使用装饰者模式

  • 想要透明并且动态地给对象增加新的职责(方法)而又不会影响其他对象
  • 给对象增加的职责在未来可能会发生改变
  • 用子类扩展功能不实际的情况下
面试题:举一个用 Java 实现的装饰模式(decorator design pattern) ?它是作用于对象层次还是类层次?

装饰模式增加强了单个对象的能力。Java IO 到处都使用了装饰模式,典型例子就是Buffered 系列类如 BufferedReader 和 BufferedWriter,它们增强了 Reader 和 Writer 对象,以实现提升性能的 Buffer 层次的读取和写入。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值