简介
之前把IO流按照类型分为了字节流和字符类,又根据流向可以分为输入流和输出。
为了精通io流我又细研究类图,发现了还能分。一个是inputStream的直接儿子类,另一个是子类Filter下孙子类。
简单来说,直接儿子类是应对不同的数据来源和场景的,Filter孙子类是增加了额外的功能。
详解
因为字符流和字节流的设计思想都类似,这里是拿字节流中输入流讲解,其他的可以举一反三的来看。
直接儿子类,通过图可知有
操作磁盘文件的FileInputStream,
操作系统生成的数据ByteArrayInputStream,
处理Object类序列化的ObjectInputStream等,
这些类都是应对不同数据的流,也就是说有一天发现了外星人需要用电脑和外星人交流,就要单独设计个外星人流。也就是说我们要在项目中碰到需要流来解决问题时,首先选择用那种直接儿子类。
FileInputStream fin = new FileInputStream("test.txt");
Filter孙子类
孙子类就是为了增加额外功能的,例如能够实现缓存、实现读取下一个、实现基本类型操作等;例如我们想操作的是磁盘文件,应用了FileInputStream,但是要想在这个类的基础上增加缓存的功能设计个缓存FileInputStream类;若是我们要操作的是ByteArrayInputStream也想要缓存功能,总不能再设计个缓存ByteArrayInputStream。为了降低代码冗余,就把这些额外的功能用装饰器设计模式抽象出来。
//先建立儿子类
FileInputStream fin = new FileInputStream("test.txt");
//需要读基本类型,就把儿子类交给了孙子类
DataInputStream din = new DataInputStream(fin);
double v = din.readDouble();
总结
只是应对不同的功能用儿子类就好,想另外增加功能,就把儿子类给孙子类操作。另外孙子类也可以再给另一个孙子,这样就拥有了两个功能。儿子类是为了场景,孙子有额外的功能。
//先建立儿子类
FileInputStream fin = new FileInputStream("test.txt");
//需要缓存,把儿子类fin交给了孙子类
BufferedInputStream bis = new BufferedInputStream(fin);
//还想读基本数据类型,再交给个孙子类一起做,拥有了两个功能
DataInputStream din = new DataInputStream(bis);
double v = din.readDouble();