04-IO资源的处理、缓冲流、转换流、对象流、打印流、Properties属性集、装饰模式

1、IO资源的处理

  • JDK1.7前的处理方式

    • // JDK1.7以前处理IO流异常
              FileWriter fw1 = null;
              try {
                   fw1 = new FileWriter("study_day11\\abc\\bos.txt");
              } catch (IOException e) {
                  System.out.println("处理创建流异常");
              } finally {
                  if (fw1 !=null){
                      try {
                          fw1.close();
                      } catch (IOException e) {
                          System.out.println("处理关闭异常");
                      }
                  }
              }
  • JDK1.7之后的处理方式

    • JDK7增加了try-with-resource语句来处理资源,该语句确保了每个资源在语句结束的时候关闭

    • try (FileWriter fw2 = new FileWriter("study_day11\\abc\\bos.txt")) {
                  fw2.write("46");
              } catch (IOException e) {
                  System.out.println("处理关闭异常");
              }

2、缓冲流

2.1、缓冲流介绍

  • 按照数据类型分类
    • 字节缓冲流
      • BufferedInputStream, BufferedOutputStream
    • 字符缓冲流
      • BufferedReader, BufferedWriter
  • 缓冲流的好处
    • 缓冲流内置的默认8K大小的缓冲区数组,减少系统IO次数,从而提高读写的效率

2.2、字节缓冲流

2.2.1、体系结构

2.2.2、字节缓冲流API

  • public BufferedInputStream(InputStream in)
    • 把基本的字节输入流包装成一个字节输入缓冲流,从而提高字节输入流读数据的性能
  • public BufferedOutputStream(OutputStream out)
    • 把基本的字节输出流包装成一个字节输出缓冲流,从而提高写数据的性能

2.2.3、字节输出缓冲流

  • public BufferedOutputStream(OutputStream out)
    • 把基本的字节输出流包装成一个字节输出缓冲流,从而提高写数据的性能

2.2.4、缓冲流的规律

  • 以Buffered开头
  • 后缀就是继承的父类

2.2.5、字节输入缓冲流

  • public BufferedInputStream(InputStream in)

    • 把基本的字节输入流包装成一个字节输入缓冲流,从而提高字节输入流读数据的性能
  • demo

    • // 1.创建缓冲字节输入流
              BufferedInputStream bis = new BufferedInputStream(new FileInputStream("study_day11\\abc\\bos.txt"));
              // 2.读数据
              int b;
              while ((b = bis.read()) != -1) {
                  System.out.println((char) b);
              }
              // 3.关闭
              bis.close();

2.2.6、案例(字节流四种复制文件)

  • 基本流读取一个字节

    • // 基本流读写一个字节
      public static void test01() throws IOException {
      // 创建输入流
      FileInputStream fis = new FileInputStream("D:/MyFileTest/高清无码.flv");
      // 创建输出流
      FileOutputStream fos = new FileOutputStream("D:/MyFileTest/高清无码1.flv");
      // 循环读写
      int b; // 保存读取的数据
      while ((b = fis.read()) != -1) {
      fos.write(b);
      }
      // 关闭流
      fos.close();
      fis.close();
      }
  • 基本流读取一个字节数组

    • // 基本流读写一个字节数组
      public static void test02() throws IOException {
      // 创建输入流
      FileInputStream fis = new FileInputStream("D:/MyFileTest/高清无码.flv");
      // 创建输出流
      FileOutputStream fos = new FileOutputStream("D:/MyFileTest/高清无码2.flv");
      // 循环读写
      byte[] buf = new byte[1024*8]; // 保存读取的数据
      int len; // 保存读取的数量
      while ((len = fis.read(buf)) != -1) {
      fos.write(buf, 0, len);
      }
      // 关闭流
      fos.close();
      fis.close();
      }
  • 缓冲流读取一个字节

    • // 缓冲流读写一个字节
      public static void test03() throws IOException {
      // 创建输入流
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/MyFileTest/高清无码.flv"));
      // 创建输出流
      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:/MyFileTest/高清无码3.flv"));
      // 循环读写
      int b; // 保存读取的数据
      while ((b = bis.read()) != -1) {
      bos.write(b);
      }
      // 关闭流
      bos.close();
      bis.close();
      }
  • 缓冲流读取一个字节数组

    • // 缓冲流读写一个字节数组
      public static void test04() throws IOException {
      // 创建输入流
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/MyFileTest/高清无码.flv"));
      // 创建输出流
      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:/MyFileTest/高清无码4.flv"));
      // 循环读写
      byte[] buf = new byte[1024 * 8]; // 8192
      int len;
      while ((len = bis.read(buf)) != -1) {
      bos.write(buf, 0, len);
      }
      // 关闭流
      bos.close();
      bis.close();
      }

2.3、字符缓冲流

2.3.1、字符输出缓冲流

  • BufferedWriter
    • 方法
      • public BufferedWriter(Writer r)
        • 把基本的字符输出流包装成一个字符输出缓冲流,从而提高字符输出流写数据的性能
    • 字符输出缓冲流新增功能
      • public String newLine()
        • 换行

2.3.2、字符输入缓冲流

  • BufferedReader
    • 方法
      • public BufferedReader(Reader r)
      • 把基本的字符输入流包装成一个字符输入缓冲流,从而提高字符输入缓冲流读数据的性能
    • 字符输入缓冲流新增功能
      • public String readLine()
        • 读取一行数据返回,如果读取没有完毕,无行可读则返回null

2.3.3、字符缓冲流为什么提高了操作数据的性能

  • 字符缓冲流自带8K缓冲区
  • 可以提高原始字符流读写数据的性能

3、转换流

3.1、字符集和字符编码的概念

  • 字符集
    • ASCII字符集
    • ISO-8859-1字符集
    • GBxxx字符集
    • Unicode字符集
  • 字符编码
    • 将字符转成n进制,称为编码
      • 如将字符转成二进制
    • 将n进制转成字符,称为解码
      • 如将二进制转换成文字

3.2、字符流读不同编码的文件乱码

  • 乱码原因
    • 文件保存到文件中的编码和读取文字时使用的编码不一致
  • 乱码解决方案
    • 保证存储和取出时编码一致即可

3.3、转换流的使用

  • InputStreamReader

    • 可以指定编码读取数据

    • demo

      • InputStreamReader isr = new InputStreamReader(new FileInputStream("study_day11\\abc\\china_gbk.txt"),"GBK");
                int ch;
                while ((ch = isr.read()) != -1){
                    System.out.println((char) ch);
                }
                isr.close();
  • OutputStreamWriter

    • 可以指定编码写数据

    • 方法

      • OutputStreamWriter(OutputStream out)
        • 使用默认编码写数据
      • OutputStreamWriter(OutputStream out, String charsetName)
        • 使用指定编码写数据
    • demo

      • OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("study_day11\\abc\\hello_gbk.txt"), "GBK");
                osw.write("你好");
                osw.close();

3.4、操作字符的时候如何选择流

  • 基本流(FileReader/FileWriter)
    • 如果不需要修改编码就使用基本流,使用更简单
  • 转换流(InputStreamReader/OutputStreamWriter)
    • 如果需要修改编码就使用转换流

3.5、案例(文件转码)

  • 步骤

    • 使用GBK编码读取文件内容
    • 使用UTF-8编码写字符数据到文件
    • 循环读写
  • 代码示例

    • package Day11.demo09转换文件编码_重点;
      import java.io.*;
      /*
      目标:将GBK编码的文本文件,转换为UTF-8编码的文本文件
      讲解:
      步骤:
      1.使用GBK编码读取文件内容
      2.使用UTF-8编码写字符数据到文件
      3.循环读写
      */
      public class Demo09 {
      public static void main(String[] args) throws IOException {
      // 1.使用GBK编码读取文件内容
      InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("DarkHorseEmployment\\src\\Day11\\demo09转换文件编码_重点\\gbk.txt"), "GBK");
      // 2.使用UTF-8编码写字符数据到文件
      OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("DarkHorseEmployment\\src\\Day11\\demo09转换文件编码_重点\\utf-8.txt"), "utf-8");
      // 3.循环读写
      int len;
      while ((len = inputStreamReader.read()) != -1) {
      System.out.println("len = " + len);
      System.out.println("(char) len = " + (char) len);
      outputStreamWriter.write((char) len);
      }
      System.out.println("写入成功!");
      // 4.关闭文件
      outputStreamWriter.close();
      inputStreamReader.close();
      }
      }

4、对象流

4.1、对象操作流分类

  • ObjectOutputStream

    • 对象输出流

    • ObjectOutputStream oos = new ObjectOutputStream(基本流);
          oos.writeObject(对象);
  • ObjectInputStream

    • 对象输入流

    • ObjectInputStream ois = new ObjectInputStream(基本流);
          ois.readObject();

4.2、对象流的使用

  • 输出流
    • ObjectOutputStream(OutputStream out)
      • 对象输出流,把对象以字节的形式写道本地文件
    • public void writeObject(Object obj)
      • 写一个对象到文件中
  • 输入流
    • ObjectInputStream(InputStream in)
      • 对象输入流,把写到本地文件中的对象读取到内存当中
    • public Object readObject()
      • 读取文件中的对象数据到文件中

4.3、对象流细节

  • 使用对象输出流将对象保存到文件时会出现NotSerializableExxception异常
  • 解决
    • 需要让类实现Serializable接口

4.4、案例(用对象流读写多个对象)

  • 步骤

    • 把若干学生对象,保存到集合中
    • 把集合序列化
    • 反序列化读取时,只需要读取一次,转换为集合类型
    • 遍历集合,打印所有的学生信息
  • demo

    • Student类

      • package Day11.demo10ObjectOutputStream对象输出流;
        import java.io.Serializable;
        public class Student implements Serializable {
        private String name;
        private int age;
        private char sex;
        public Student(String name, int age, char sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        }
        public Student() {
        }
        public String getName() {
        return name;
        }
        public void setName(String name) {
        this.name = name;
        }
        public int getAge() {
        return age;
        }
        public void setAge(int age) {
        this.age = age;
        }
        public char getSex() {
        return sex;
        }
        public void setSex(char sex) {
        this.sex = sex;
        }
        @Override
        public String toString() {
        return "Student{" +
        "name='" + name + '\'' +
        ", age=" + age +
        ", sex=" + sex +
        '}';
        }
        }
    • Demo类

      • public class Demo10 {
        public static void main(String[] args) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("F:\\GoodGoodStudy\\DarkHorseEmployment\\src\\Day11\\demo10ObjectOutputStream对象输出流\\students.txt"));
        objectOutputStream.writeObject(new Student("梁朝伟", 44, '男'));
        objectOutputStream.writeObject(new Student("黎明", 49, '男'));
        objectOutputStream.writeObject(new Student("刘德华", 46, '男'));
        objectOutputStream.writeObject(new Student("郭富城", 44, '男'));
        objectOutputStream.writeObject(new Student("刘亦菲", 18, '女'));
        objectOutputStream.close();
        }
        }

        public class Demo11 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {

        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("DarkHorseEmployment\\src\\Day11\\demo10ObjectOutputStream对象输出流\\students.txt"));
        ArrayList<Student> people = new ArrayList<>();
        while (true) {
        try {
        Student o = (Student) objectInputStream.readObject();
        people.add(o);
        }catch (EOFException e) {
        break;
        }
        }
        System.out.println("people = " + people);
        }

        }


5、打印流

  • 作用
    • 打印流可以实现方便、高效的打印数据到文件中去
  • 打印流构造器
    • PrintStream(File file)
      • 创建PrintStream,指定打印的目的地
    • PrintStream(String fileName)
      • 创建PrintStream,指定打印的目的地
    • PrintStream(OutputStream out)
      • 创建PrintStream,指定打印的目的地
  • 方法
    • print(Xxx x)
      • 打印数据,不换行
    • println(Xxx x)
      • 打印数据,换行

6、Properties属性集

6.1、Properties体系结构

6.2、Properties作为集合使用

  • Properties实现了Map接口,就是一个双列集合,可以存储键值对
    • PS:Properties集合的键值对都是字符串类型
  • Properties可以结合流进行操作,可以把集合中的数据保存到流中,也可以从流中来加载数据

6.3、Properties作为集合的特有方法

  • Object setProperty(String key, String value)
    • 添加键和值,键和值都是String类型
    • String getProperty(String key)
    • 通过键获取值
    • Set stringPropertyNames()
    • 获取所有的键

6.4、Properties和IO流结合的方法

  • 方法
    • void load(Reader reader)
      • 从输入字符流读取属性列表(键和值)
    • void store(Writer writer, String comments)
      • 将Properties中的键和值写入输出字符流中
    • void load(InputStream inStream)
      • 从输入字节流读取属性列表(键和元素对)
    • void store(OutputStream out, String comments)
      • 将Properties中的键和值写入输出字节流中

6.5、使用Properties的load方法加载文件中配置信息代码示例

  • public static void testLoad() throws IOException {
            Properties pp = new Properties();
            System.out.println("加载前: " + pp);
            pp.load(new FileReader("study_day11\\abc\\pp.properties"));
            System.out.println("加载后: " + pp);
        }

7、装饰模式

  • 装饰设计模式的作用
    • 可以增强原本的类和扩展类的功能
  • 装饰设计模式有三个角色
    • 共同的接口
    • 原对象
    • 装饰对象

8、IO流总结

posted @   OnlyOnYourself-Lzw  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示