美文网首页
从源码设计角度理解Java IO

从源码设计角度理解Java IO

作者: remax1 | 来源:发表于2020-06-01 14:58 被阅读0次

概述

Java的核心库java.io提供了全面的IO接口。包括:文件读写、标准设备输出等。Java中IO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。

IO是指对数据流的输入和输出,也称为IO流,IO流主要分为两大类,字节流和字符流。字节流可以处理任何类型的数据,如图片,视频等,字符流只能处理字符类型的数据。

相关类或接口

InputStream -- 字节输入流(接口)

OutputStream -- 字节输出流(接口)

Reader -- 字符输入流(接口)

Writer -- 字符输出流(接口)

File -- 文件类

RandomAccessFile -- 随机存储文件类

设计模式之装饰者模式

先看一段代码:

 DataOutputStream outputStream = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(file)));

被这么多嵌套给绕晕了。。。java io就是装饰者模式的典型,接下来我将围绕着装饰模式来展开IO相关类的学习。

图片.png

装饰模式中的角色:
抽象构件(Component)角色:Component是一个抽象类或接口,是要包装的原始对象。

具体构件(ConcreteComponent)角色:是Component的实现类,最终要装饰的实际对象。

装饰(Decorator)角色:是一个抽象类,继承或实现了Component的接口,同时它持有一个对Component实例对象的引用,也可以有自己的方法。

具体装饰(ConcreteDecorator)角色:是Decorator的实现类,是具体的装饰者对象,负责给ConcreteComponent附加责任。

java流类图结构

图片.png
转载自:https://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html

装饰模式之InputStream(字节流)

从IO中输入字节流的继承图中可以看出。

1)InputStream是所有数据字节流的父类。
是个接口,也是上面提到的抽象构件(Component)角色。

2)ByteArrayInputStream、StringBufferInputStream、FileInputStream、ObjectInputStream是基本的介质流,它们分别从Byte数组、StringBuffer、本地文件和对象中读取数据,PipedInputStream是从与其他线程共用的管道中读取数据。
他们都是具体的装饰对象,也就是上面的具体构件(ConcreteComponent)角色。

3)BufferedInputStream、DataInputStream是实际的装饰器对象。
也就是具体装饰(ConcreteDecorator)角色。

看到这里也许会有一些疑问,装饰角色呢,也就是那个抽象类去哪了,在这里我觉得FilterInputStream就是这个角色,不过它不是抽象类,在使用中也很少用到,姑且这么认为把。

上面说了,装饰角色会持有一个对抽象父类InputStream的引用来完成装饰模式。现在去验证下。

//构造时传入引用
public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }

//直接用父类的引用
 public DataInputStream(InputStream in) {
        super(in);
    }

装饰模式之OutputStream(字节流)

从IO中输入字节流的继承图中可以看出。

1)OutputStream是所有输出字节流的父类,它是一个抽象类。
是个接口,也是上面提到的抽象构件(Component)角色。

2)ByteArrayOutputStream、FIleOutputStream是两种基本的介质,它们分别向Byte 数组,和本地文件中写入数据。PipedOutputStream是从与其他线程共用的管道中写入数据。
他们都是具体的装饰对象,也就是上面的具体构件(ConcreteComponent)角色。

3)BufferdOutputStream、DataOutputStream是实际的装饰器对象。
也就是具体装饰(ConcreteDecorator)角色。

原理同InputStream

字符输入流Reader

在上面的继承关系图中可以看出:

1、Reader是所有的输入字符流的父类,它是一个抽象类。

2、CharReader、StringReader 是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedInputReader 是从与其他线程共用的管道中读取数据。

3、BuffereReader 很明显的是一个装饰器对象,它和其子类复制装饰其他Reader对象。

4、FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰。

字符输出流Writer

在上面的关系图中可以看出:

1、Writer 是所有输出字符流的父类,它是一个抽象类。

2、CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedInputWriter 是从与其他线程共用的管道中读取数据。

3、BuffereWriter 很明显是一个装饰器,他和其子类复制装饰其他Reader对象。

4、FilterWriter 和PrintStream 及其类似,功能和使用也非常相似。

区别与联系

· 读写单位的不同:字节流以字节(8bit)为单位。字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

· 处理对象不同:字节流可以处理任何类型的数据,如图片、avi等,而字符流只能处理字符类型的数据。

InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。

RandomAccessFile

1.既可以读也可以写
RandomAccessFile不属于InputStream和OutputStream类系。它是完全独立的类

2.可以指定位置读写
RandomAccessFile能在文件里面的前后移动,在文件里移动用seek()。可以用于多线程下载或多个线程同时写数据到文件。

总结

理解本篇文章最主要的还是对装饰器模式有所了解,了解之后才能构建体系,现在知道开头的一层层的嵌套是什么意思了把。。。

相关文章

网友评论

      本文标题:从源码设计角度理解Java IO

      本文链接:https://www.haomeiwen.com/subject/mcdjzhtx.html