阶段二33_面向对象高级_IO[转换流,对象流]

知识点:

 1.转换流:InputStreamReader,OutputStreamWriter
 2.对象流:ObjectInputStream,ObjectOutputStream

一.转换流

1.转换流原理图
阶段二33_面向对象高级_IO[转换流,对象流]_第1张图片

2.转换流概述

转换流就是来进行字节流和字符流之间转换的
InputStreamReader是从字节流到字符流的桥梁
OutputStreamWriter是从字符流到字节流的桥梁

3.在JDK11之前,转换流需要,指定编码读写

public class ConvertedDemo1 {
    public static void main(String[] args) throws IOException {
        //在JDK11之前,转换流需要,指定编码读
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\apple\\Desktop\\a.txt"),"gbk");
        int ch;
        while((ch = isr.read())!=-1){   System.out.println((char) ch); }
        isr.close();
        //在JDK11之前,转换流需要,指定编码写
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\apple\\Desktop\\b.txt"),"UTF-8");
        osw.write("我爱学习,谁也别打扰我");
        osw.close();
        
        //在JDK11之后,字符流新推出了一个构造,也可以指定编码表
        FileReader fr = new FileReader("C:\\Users\\apple\\Desktop\\a.txt", Charset.forName("gbk"));
        int ch;
        while ((ch = fr.read())!=-1){ System.out.println((char) ch); }
        fr.close();
    }
}

二.对象流

1.对象操作流的特点
可以把对象以字节的形式写到本地文件,直接打开文件,是读不懂的,需要再次用对象操作流读到内存中

2.对象操作流

对象操作输入流:ObjectInputStream
对象操作输出流:ObjectOutputStream

3.对象操作输入流ObjectInputStream入门案例
对象操作输入流,写到(序列化)本地文件a.txt中:

public class ConvertedDemo3 {
    public static void main(String[] args) throws IOException {
        //如果想要这个类的对象能被序列化,那么这个类必须要实现一个接口.Serializable
        //Serializable 接口的意义
        //称之为是一个标记性接口,里面没有任何的抽象方法
        //只要一个类实现了这个Serializable接口,那么就表示这个类的对象可以被序列化.
        User user = new User("zhangsan","qwer");
        
        //对象操作输入流,写到本地文件a.txt中
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
        oos.writeObject(user);
        oos.close();
    }
}

对象操作输出流,本地文件a.txt读到(反序列化)内存中:

public class ConvertedDemo4 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
        User o = (User) ois.readObject();
        System.out.println(o);
        ois.close();
    }
}

4.对象操作流注意点:

  用对象序列化流序列化了一个对象后,假如我们修改了对象所属的Javabean类,读取数据会不会出问题呢?
  会出问题,会抛出InvalidClassException异常

  如果出问题了,如何解决呢?
  给对象所属的类加一个serialVersionUID 
  private static final long serialVersionUID = 42L;

  如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
  给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
  private transient String password;

5.练习:

用对象操作流读写多个对象
需求:创建多个Javabean类对象写到文件中,再次读取到内存。
思路:
创建学生对象
利用对象操作输出流写到本地
利用对象操作输入流读到内存
public class ConvertedDemo7 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student s1 = new Student("杜子腾",16);
        Student s2 = new Student("张三",23);
        Student s3 = new Student("李四",24);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        //我们往本地文件中写的就是一个集合
        oos.writeObject(list);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
        //读本地文件一个集合对象
        ArrayList<Student> list2 = (ArrayList<Student>) ois.readObject();
        for (Student student : list2) {
            System.out.println(student);
        }
        ois.close();
        
        /*
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
        oos.writeObject(s1);
        oos.writeObject(s2);
        oos.writeObject(s3);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
        Object obj;
        while(true){
           try {
               Object o = ois.readObject();
               System.out.println(o);
           } catch (EOFException e) {  break; }
        }
        */
    }
}

三.更多精彩内容
http://www.gxcode.top/code
阶段二33_面向对象高级_IO[转换流,对象流]_第2张图片
阶段二33_面向对象高级_IO[转换流,对象流]_第3张图片

你可能感兴趣的:(阶段二Java,java,转换流,对象流)