zoukankan      html  css  js  c++  java
  • 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写入或者读取到缓冲区,
            然后再通过一系列的转换(字节-->字符-->,字节-->对象...)达到要求  (☆)
    
  • 相关阅读:
    设计模式(五)——单例模式
    设计模式(四)——工厂模式
    设计模式(三)—— 装饰者模式
    设计模式(二)—— 观察者模式
    JAVA环境配置
    在线求中位数
    不能对自己期望太大,但总是要拼一拼
    Leetcode | String to Integer (atoi)
    Leetcode | Simplify Path
    Leetcode | Longest Common Prefix
  • 原文地址:https://www.cnblogs.com/xw1203/p/15035785.html
Copyright © 2011-2022 走看看