美文网首页IO
Java IO流详解(二)——IO流的框架体系

Java IO流详解(二)——IO流的框架体系

作者: Android进阶与总结 | 来源:发表于2017-03-09 14:58 被阅读838次
    本篇文章主要介绍IO流的分类、概念以及IO流中的四大基类,通过对IO流中的框架体系进行介绍,对IO流有一个整体的了解。
    

    一、IO流的概念

    Java的IO流是实现输入/输出的基础,它可以方便地实现数据的输入/输出操作,在Java中把不同的输入/输出源抽象表述为"流"。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
    流有输入和输出,输入时是流从数据源流向程序。输出时是流从程序传向数据源,而数据源可以是内存,文件,网络或程序等。
    二、IO流的分类
    1.输入流和输出流

    根据数据流向不同分为:输入流和输出流。

    输入流:只能从中读取数据,而不能向其写入数据。
    输出流:只能向其写入数据,而不能从中读取数据。
    

    如下如所示:对程序而言,向右的箭头,表示输入,向左的箭头,表示输出。

    2.字节流和字符流

    字节流和字符流和用法几乎完全一样,区别在于字节流和字符流所操作的数据单元不同。
    字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:
    (1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
    (2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

    只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。
    3.节点流和处理流

    按照流的角色来分,可以分为节点流和处理流。
    可以从/向一个特定的IO设备(如磁盘、网络)读/写数据的流,称为节点流,节点流也被成为低级流。
    处理流是对一个已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能,处理流也被称为高级流。

    //节点流,直接传入的参数是IO设备
    FileInputStream fis = new FileInputStream("test.txt");
    //处理流,直接传入的参数是流对象
    BufferedInputStream bis = new BufferedInputStream(fis);

    当使用处理流进行输入/输出时,程序并不会直接连接到实际的数据源,没有和实际的输入/输出节点连接。使用处理流的一个明显好处是,只要使用相同的处理流,程序就可以采用完全相同的输入/输出代码来访问不同的数据源,随着处理流所包装节点流的变化,程序实际所访问的数据源也相应地发生变化。
    实际上,Java使用处理流来包装节点流是一种典型的装饰器设计模式,通过使用处理流来包装不同的节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入/输出功能。
    三、IO流的四大基类

    根据流的流向以及操作的数据单元不同,将流分为了四种类型,每种类型对应一种抽象基类。这四种抽象基类分别为:InputStream,Reader,OutputStream以及Writer。四种基类下,对应不同的实现类,具有不同的特性。在这些实现类中,又可以分为节点流和处理流。下面就是整个由着四大基类支撑下,整个IO流的框架图。

    InputStream,Reader,OutputStream以及Writer,这四大抽象基类,本身并不能创建实例来执行输入/输出,但它们将成为所有输入/输出流的模版,所以它们的方法是所有输入/输出流都可以使用的方法。类似于集合中的Collection接口。
    1.InputStream

    InputStream 是所有的输入字节流的父类,它是一个抽象类,主要包含三个方法:

    //读取一个字节并以整数的形式返回(0~255),如果返回-1已到输入流的末尾。
    int read() ;
    //读取一系列字节并存储到一个数组buffer,返回实际读取的字节数,如果读取前已到输入流的末尾返回-1。
    int read(byte[] buffer) ;
    //读取length个字节并存储到一个字节数组buffer,从off位置开始存,最多len, 返回实际读取的字节数,如果读取前以到输入流的末尾返回-1。
    int read(byte[] buffer, int off, int len) ;

    2.Reader

    Reader 是所有的输入字符流的父类,它是一个抽象类,主要包含三个方法:

    //读取一个字符并以整数的形式返回(0~255),如果返回-1已到输入流的末尾。
    int read() ;
    //读取一系列字符并存储到一个数组buffer,返回实际读取的字符数,如果读取前已到输入流的末尾返回-1。
    int read(char[] cbuf) ;
    //读取length个字符,并存储到一个数组buffer,从off位置开始存,最多读取len,返回实际读取的字符数,如果读取前以到输入流的末尾返回-1。
    int read(char[] cbuf, int off, int len)

    对比InputStream和Reader所提供的方法,就不难发现两个基类的功能基本一样的,只不过读取的数据单元不同。

    在执行完流操作后,要调用close()方法来关系输入流,因为程序里打开的IO资源不属于内存资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件IO资源。

    除此之外,InputStream和Reader还支持如下方法来移动流中的指针位置:

    //在此输入流中标记当前的位置
    //readlimit - 在标记位置失效前可以读取字节的最大限制。
    void mark(int readlimit)
    // 测试此输入流是否支持 mark 方法
    boolean markSupported()
    // 跳过和丢弃此输入流中数据的 n 个字节/字符
    long skip(long n)
    //将此流重新定位到最后一次对此输入流调用 mark 方法时的位置
    void reset()

    3.OutputStream

    OutputStream 是所有的输出字节流的父类,它是一个抽象类,主要包含如下四个方法:

    //向输出流中写入一个字节数据,该字节数据为参数b的低8位。
    void write(int b) ;
    //将一个字节类型的数组中的数据写入输出流。
    void write(byte[] b);
    //将一个字节类型的数组中的从指定位置(off)开始的,len个字节写入到输出流。
    void write(byte[] b, int off, int len);
    //将输出流中缓冲的数据全部写出到目的地。
    void flush();

    4.Writer

    Writer 是所有的输出字符流的父类,它是一个抽象类,主要包含如下六个方法:

    //向输出流中写入一个字符数据,该字节数据为参数b的低16位。
    void write(int c);
    //将一个字符类型的数组中的数据写入输出流,
    void write(char[] cbuf)
    //将一个字符类型的数组中的从指定位置(offset)开始的,length个字符写入到输出流。
    void write(char[] cbuf, int offset, int length);
    //将一个字符串中的字符写入到输出流。
    void write(String string);
    //将一个字符串从offset开始的length个字符写入到输出流。
    void write(String string, int offset, int length);
    //将输出流中缓冲的数据全部写出到目的地。
    void flush()

    可以看出,Writer比OutputStream多出两个方法,主要是支持写入字符和字符串类型的数据。

    使用Java的IO流执行输出时,不要忘记关闭输出流,关闭输出流除了可以保证流的物理资源被回收之外,还能将输出流缓冲区的数据flush到物理节点里(因为在执行close()方法之前,自动执行输出流的flush()方法)

    以上内容就是整个IO流的框架介绍。

    相关文章

      网友评论

        本文标题:Java IO流详解(二)——IO流的框架体系

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