关于Java IO流 你知道多少

时间:2020-12-24 22:42:20

下面是我近一段时间,复习IO流的一些知识点:

一.分类:

   1.  按流向分类:

          输入流:程序可以从中读取数据的流;

          如:InputStream/Reader

          输出流:程序可以向其写入数据的流;

          如:OutputStream/Writer

   2.按数据传输单位分类:

          字节流:以字节(8位二进制)为单位进行处理。主要用于读写诸如图像或声音的二进制数据。

          如:FileInputStream/FileOutputStream

          字符流:以字符(16位二进制)为单位进行处理。主要用于读写诸如文本文件的数据。

          如:FileReader/FileWriter

          注意:字符流可以看做是一种包装流,因为在字符流源码中底层还是通过字节流进行读写操作。

   3.按功能分类:

         节点流:直接与原始数据存在的特定介质(如磁盘文件或其他外部设备、内存某区域)打交道的流。

         如:FileInputStream/FileOutputStream/FileReader/FileWriter

         过滤流:使用其它的流作为输入源或输出目的地,对流中的数据提供进一步处理的流。其他的流可以是节点流,

         也可以是另一种过滤流。

         例如:BufferedInputStream/DataInputStream

         注意:过滤流必须建立在节点流之上,过滤流不能单独使用,一个输入流链或输出流链中一定有且只有一个节点流;可以没有,

         也可以有多个过滤流。

二. IO流概略图:

   关于Java IO流 你知道多少

三.过滤流:

   说白了,过滤流就是不能直接与目标打交道,比如说:如磁盘文件或其他外部设备、内存某区域; 那 反之 节点流是能直接与目标打交道的;

   FilterOutputStream(OutputStream out) : 此类是过滤输出流的所有类的超类(父类)

   需要传入一个OutputStream。

    在InputStream和OutputStream的子类中,FilterInputStream和FilterOutputStream是过滤流,

    其又派生出子类DataInputStream和DataOutputStream数据输入流和数据输出流。

    过滤流的主要特点是对节点流中的数据进行某些加工、处理,并提供一些友好的方法供用户进行输入、输出操作以及流控制

  例如,DataInputStreamDataOutputStream 以读写Java基本数据类型的数据方便读写操作。

    BufferedInputStream可以对任何种类的输入流进行带缓冲区的封装,以达到性能的改善(可减少程序I/O操作次数,提高程序执行效率)。

  Java利用过滤流可以在读/写数据的同时对数据进行处理。

    使用过滤流时要注意:必须将过滤流和某个输入流或输出流(节点流)连接而在程序设计中,连接是通过在过滤流的构造方法中指定的参数(节点流)

  来实现的,多数利用 FileInputStreamFileOutputStream的对象作节点流参数

    如:

        FileInputStream in=new FileInputStream("data.txt");

        DataInputStream dfin=new DataInputStream (in);

   实现了过滤流dfin和文件输入流in连接。在读写数据时,我们应该使用过滤流链中的最后一个过滤流进行实际的读写操作

   解释一下:过滤流链 -- 当多个过滤流链接在一起时,就形成了过滤流链;(其实,在设计模式中是:  “装饰模式”)

 

四. 字符流与字节流的转换:

   前几天,碰到一个问题,就是字符流与字节流的转换,结果吃了大亏,查看了一下源码才发现其中的秘密!

   JDK 1.6中解释:

  1. InputStreamReader:字节到字符的桥梁
  2. OutputStreamWriter:字符到字节的桥梁
   下面我给大家通俗的解释一下:

   InputStreamReader: 是Reader的最重要的具体子类,InputStreamReader从其底层字节输入流(如FileInputStream)中读取字节,

   根据指定的编码方式(字符集编码)将这些字节转换为字符,并返回这些字符。我们可以在构造函数中指定要读取的字节输入流和所用的编码方式:

   InputStreamReader(InputStream in) :创建一个使用默认字符集的 InputStreamReader。

   InputStreamReader(InputStream in,String charsetName): 创建使用指定字符集的 InputStreamReader。


   OutputStreamWriter:是Writer的最重要的具体子类,OutputStreamWriter会接收需要输出的字符。它根据指定的编码方式(字符编码)

   将这些字符转换为字节,然后调用底层字节输出流输出。它的构造函数指明了字符输出流和使用的编码方式

   OutputStreamWriter(OutputStream out):创建使用默认字符编码的 OutputStreamWriter。

   OutputStreamWriter(OutputStream out,String charsetName) :创建使用指定字符集的 OutputStreamWriter。

 

   何时使用转换流:

  1. 当字节和字符之间有转换动作时;
  2. 流操作的数据需要编码或解码时。

五. InputStream与OutputStream要掌握的问题:

  我们打开InputStream与OutputStream发现:

  (1) 类 InputStream

 


abstract int read()

从输入流中读取数据的下一个字节。

int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。

  (2)类 OutputStream


void write(byte[] b)

将 b.length 个字节从指定的 byte 数组写入此输出流。

void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

abstract void write(int b)
将指定的字节写入此输出流。

总结:由此我们看以看出来,InputStream与OutputStream都有一个抽象方法,我以OutputStream为例,

打开源代码发现,write(byte abyte0[]) 内部就是调用的write(byte[] b, int off, int len),

而write(byte[] b, int off, int len)内部是调用的write(int i),所以InputStream与OutputStream 调用的最底层方法

分别应该是read()、write(int b),而这两个最重要的底层方法又都是抽象方法,这样继承InputStream与OutputStream

的子类都必须提供read()、write(int b)的实现,从而造成的后果就是每个子类的实现方式都不一样。


好了,先总结这么多吧!如果我写的有不对的地方,欢迎大家即使的指正 --- 大饼