JavaSe_IO流总结

一、IO流的概念:

    I:input输入
    O:output输出

        1 流的分类:
                 1.1 根据流向不同可以分:InputStream和OutputStream
                 1.2 根据数据源不同可以分为:FileInputStream、ZipFileInputStream等
                 1.3 根据内容的不同可以分为:字节流和字符流

        2 Java程序中的流:
                 2.1 Java程序通过流从其他地方获取数据
                 2.2 数据源和目的地是相对的,如果以文件/数据库为中心,Java程序是数据源文件/数据数是目的地
                 2.3 如果以Java程序为中心,那么文件/数据库是数据源,Java程序为目的地

                 2.4 一般情况下,我们以程序为中心:
                         我们把数据源指向Java程序的流称为输入流(Input)
                         把Java程序指向数据源的流称作为输出流(Output)

        3、Java针对输入输出提出两个顶级抽象类:
                 3.1 Java.io.InputStream:输入流
                        根据数据源的不同,InputStream有可以分为众多的子类
                        class FileInputStream extends InputStream(☆)
                 3.2 Java.io.OutputStream:输出流
                        根据数据源的不同,OutputStream也可以分为众多的子类:
                        class FileOutputStream extends OutputStream

二、划分:

        1、按照流向来分:输入和输出流
        2、按照处理的内容来分:字节流和字符流
        3、按照功能来分:文件流、缓冲流、打印流、对象流、转换流、内存流、标准输入输出流...

三、字节流

        调用:
        1、FileInputStream():将磁盘上的文件中数据读取到Java程序中
              构造方法: FileInputStream(String filePath)/FileInputStream(File file)
                1.1 int read(byte[] bytes); 获取文件中的一个字节的数据
                                        参数bytes:一次性尝试读取bytes.length个字节
                                        如果数据源已经读完,那么这个方法返回为-1。
                                        // 数据容量大小固定,当读取的数据字节数超过数组容量最值之后,从下一字节开始覆盖掉原来的对应下标的数据再存储下一数据

                1.2 void close():关闭流,文件操作完后,关闭文件/释放资源。如果不释放资源,表示这个文件一直被Java程序占用,无法进行删除等操作。

                1.3 int available():返回流中还有多个没有被读取的字节数,方法返回值为0代表读取完毕。

        2、FileOutputStream():把Java程序中的数据输入到磁盘上的文件中
                1.1 void write(int i); 将程序中的数据逐个的方式写入磁盘上的文件中
                    write(byte[] bytes):会将bytes数组中的所有内容写入磁盘上的文件中。

四、字符流

        1、工作原理:使用通过字节将文件中的字节数据读取到内存当中
        2、字符流的祖宗类:Reader 和 Writer
        3、字符流:相对于字节流每次需要操作字节数数组而言,字符流可以直接操作字符。

        4、 通过FileInputStream读取文件文件中的数据的时候,我们需要手动将读取到的byte数组转为字符串。
           现在需要手动转的过程被封装到了FileReader中。

        5、Reader类:
                        5.1 常用的子类:FileReader extends InputStreamReader extends Reader
                            ① FileReader:
                                FileReader(File file)
                                FileReader(String filepath):绑定一个filepath指定的文件,从这个文件中获取
                            ② 常用方法:
                                read():读取数据
                                close():关闭文件
                                flush():刷新缓冲区
                                 当缓冲区不足8k的时候,必须手动刷新缓冲区,将缓冲区的数据写入到磁盘文件中,否则会导致数据丢失

                             缓冲区:进行转换的字节数据会存放在缓冲区,当缓冲区满了之后就会把字节数据通过FileOutputStream写入到磁盘上的文件中
       
        6、Writer类:
                        6.1 FileWriter:
                             ① FileWriter extends Writer
                                 void write(char cbuf[]) throws IOException 相当于:void write(char cbuf[]) throws IOException
                                 void write(char cbuf[], int off, int len) throws IOException
                                 void write(int c) throws IOException
                                 void write(Stirng str) throws IOException
                                 void write(Stirng str,String off, len) throws IOException
               
                            ② 常用方法:
                                 write():把数据写入到磁盘
                                 close():关闭文件
                                 flush():刷新缓冲区

五、缓冲流

        1、在Java程序不需要磁盘上的数据的时候,缓冲流的的底层就首先调用fis从磁盘上获取一部分方法缓冲区中,然后Java程序需要数据的时候
                不是直接区磁盘上读取,而是缓冲区。
        2、生活中的例子:你去看一个视频,但是你的网很卡,这个时候你就会暂停视频,让它缓冲一会儿,可以去干其他事情,等视频缓冲的差不多了然后再去看视频。

        3、BufferedInputStream执行步骤:
                3.1、当调用BIS的read方法,底层就会通过fis调用read(byte[] bytes)从文件中获取8kb的数据量,然后把8kb的数据放在缓冲区中,就拷贝1kb到bytes数组中。
                3.2、下次调用BIS的read()方法的时候就不会去磁盘上读取数据,而从缓冲区中读取数据。
                3.3、假设缓冲区中没有数据,它就进行第一步操作

                // ①、真正去文件中读取字节数据的字节流
                    FileInputStream fis = new FileInputSt
                // ②、创建缓冲流对象,并且规定缓冲区为4kb
                    BufferedInputStream bis = new BufferedInputStream
                // ③、通过缓冲流读取数据(一次性读取一行)
                     byte[] bytes = new byte[1024];
                     int len;
                     while ((len = bis.read(bytes))!=-1){
                         System.out.println(new String(byt
                     }
                // ④、释放资源,关闭流
                        bis.close();

六、转换流

        1、转换流 = 字节流+编码表, 就是为了程序不要直接接触字节数据而且能看得懂的字符数据。

	2、InputStreamReader: 字节输入流转为字符输入流
		之前讲的FileReader就是InputStreamReader的一个子类: FileReader extends InputStreamReader

	     2.1 InputStreamReader的工作原理:
                     ①、通过字节流(构造方法传入进来的字节)读取到字节数据
                     ②、把上一步读取到的字节数据报错到缓冲区中
                     ③、通过编码表将缓冲区中的字节数据转为具体的字符

        3、OutputStreamWriter:字节输出流转为字符输出流
                之前将的FileWriter就是OutputStreamWriter的一个子类

七、对象流

        1、对象流概述:
            用于从流中读取对象的,可以用于读写任意类型的对象
            1.1 ObjectInputStream 称为 反序列化流,利用输入流从文件中读取对象
                    方法  readObject()
            1.2 ObjectOutputStream 称为 序列化流,利用输出流向文件中写入对象
        	    方法  writeObject()

            1.3 特点:用于操作对象。可以将对象写入到文件中,也可以从文件中读取对象。

            1.4 ObjectOutputStream在使用的时候,一定要保证保存的对象实现Serializable接口

            1.5 注意:
    		使用对象输出流写出对象,只能使用对象输入流来读取对象
    		只能将支持 java.io.Serializable 接口的对象写入流中
        2、对象流操作的4细节:
                ①、写入对象的顺序就是获取对象的顺序。
                ②、修改已经被写入文件的对象类的属性,再次从文件中读取该对象会报InvalidClassException异常
                ③、类的成员属性也要实现Serializable接口
                ④、静态变量属于类,不会被序列化到磁盘

        3、使用对象输出流和读对象输入流写对象
                Exception in thread "main" java.io.NotSerializableException:
                Serializable:序列号,是一个标识接口,只起标识作用,没有方法
      		  当一个类的对象需要IO流进行读写的时候,这个类必须实现该接口

        4、解决对实现序列化接口出现的黄色警告问题
                Exception in thread "main" java.io.InvalidClassException
                当 Serialization 运行时检测到某个类具有以下问题之一时,抛出此异常
            	    ①、该类的序列版本号与从流中读取的类描述符的版本号不匹配
            	    ②、该类包含未知数据类型
            	    ③、该类没有可访问的无参数构造方法
        
        5 transient:(瞬态) 标注的属性不会被序列化

八、打印流

        1、PrintStream extends OutputStream
        2、PrintWriter
                println():打印并换行
                print():打印不换行

        3、打印重定向:
                System.setIn(InputStream in)
                System.setOut(OutputStream out)

九、标准输入输出流

        1、标准输入流:
                System.in, 数据源是控制台
        2、标准输出流:
                System.out,目的地是控制台

                println:打印并且换行
                println方法可以打印任何类型的数据:println(Object o)
                底层是先调用对象的toString()转为字符串,然后把字符打印在控制台上

十、总结

        按照流向来分:输入和输出流
        按照处理的内容来分:字节流和字符流
        按照功能来分:文件流、缓冲流、打印流、对象流、转换流、内存流、标准输入输出流...
                
                不管使用那种流,只要是和文件操作相关最终就是使用(字节流操作)FileOutputStream或者FileInputStream写入或者读取到缓冲区,
        然后再通过一系列的转换(字节-->字符-->,字节-->对象...)达到要求  (☆)
posted @ 2021-07-20 16:51  卡萨丁荆轲  阅读(55)  评论(0编辑  收藏  举报