缓冲流、转换流、序列化流

目录

 

一、缓冲流

1.缓冲流的作用

2.缓冲流的分类

3.字节缓冲流的介绍和使用

4.字符缓冲流的介绍和使用

5.综合练习:文本排序

二、转换流

1.字符编码

2.字符集

3.编码引出的问题

4.InputStreamReader类

5.OutputStreamWriter类

三、序列化流

1.什么是序列化流

2.ObjectOutputStream类的使用

(1)构造方法

(2)序列化操作的前提

(3)写出对象方法

3.ObjectInputStream类的使用

(1)构造方法

(2)反序列化操作的异常分析

(3)读取对象方法

4.序列化多个对象练习

四、打印流PrintStream

1.介绍

2. 构造方法

3.小练习:改变打印流向


一、缓冲流

1.缓冲流的作用

缓冲流又叫增强流,用来给四大基本流做性能方面的加强。

2.缓冲流的分类

字节缓冲流: BufferedInputStream , BufferedOutputStream

字符缓冲流: BufferedReader , BufferedWriter

3.字节缓冲流的介绍和使用

(1)字节缓冲流的构造

public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。

public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。

4.字符缓冲流的介绍和使用

(1)字符缓冲流的构造

public BufferedReader(Reader in) :创建一个 新的缓冲输入流。

public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。

(2)特有方法

BufferedReader: public String readLine() : 读一行文字。

BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。

5.综合练习:文本排序

HashMap<String, String> linemap = new HashMap<>();
        //创建流对象
        try (BufferedReader br = new BufferedReader(new FileReader("出师表"));
             BufferedWriter bw = new BufferedWriter(new FileWriter("出师表02.txt"));) {
            String line = null;
            //读取数据
            while ((line = br.readLine()) != null) {
                //解析文本
                String[] split = line.split("\\.");
                //保存到集合
                linemap.put(split[0], split[1]);
            }
            //遍历集合
            for (int i = 1; i <= linemap.size(); i++) {
                //获取map中文本
                String value = linemap.get(String.valueOf(i));
                //写出拼接文本
                bw.write(i + "." + value);
                //换行
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

二、转换流

1.字符编码

就是一套自然语言的字符与二进制数之间的对应规则。

编码:字符通过编码转成对应的码值(看的懂的变为看不懂的)

解码:码值通过解码转成对应的字符(看不懂的变为看的懂的)

2.字符集

是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。

3.编码引出的问题

在IDEA中,使用FileReader 读取项目中的文本文件。由于IDEA的设置,都是默认的UTF-8 编码,所以没有任何问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。

4.InputStreamReader类

转换流java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。

(1)构造方法

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

InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。

5.OutputStreamWriter类

转换流java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。

(1)构造方法

OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。

OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。

三、序列化流

1.什么是序列化流

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的数据等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

2.ObjectOutputStream类的使用

(1)构造方法

public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream。

(2)序列化操作的前提

一个对象要想序列化,必须满足两个条件:

①该类必须实现java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException 。

②该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。

(3)写出对象方法

public final void writeObject (Object obj) : 将指定的对象写出。

3.ObjectInputStream类的使用

(1)构造方法

public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。

(2)反序列化操作的异常分析

①InvalidClassException异常

当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException 异常。发生这个异常的原因如下:

A.该类的序列版本号与从流中读取的类描述符的版本号不匹配

B.该类包含未知数据类型

C.该类没有可访问的无参数构造方法

Serializable 接口给需要序列化的类,提供了一个序列版本号。serialVersionUID 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。

②ClassNotFoundException异常

序列化前后,被序列化类被删除了。

(3)读取对象方法

public final Object readObject () : 读取一个对象。

4.序列化多个对象练习

分析:

(1)把若干学习对象 ,保存到集合中。

(2)把集合序列化。

(3)反序列化读取时,只需要读取一次,转换为集合类型。

(4)遍历集合,可以打印所有的学生信息

代码如下:

public class Student implements Serializable {
    private static final long serialVersionUID = 8002194731998770433L;
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    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 static void main(String[] args) throws Exception {
        // 创建 学生对象
        Student student = new Student("老王", 20);
        Student student2 = new Student("老张", 22);
        Student student3 = new Student("老李", 24);
        ArrayList<Student> arrayList = new ArrayList<>();
        arrayList.add(student);
        arrayList.add(student2);
        arrayList.add(student3);
        // 序列化操作
        serializ(arrayList);
        // 反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.txt"));
        // 读取对象,强转为ArrayList类型
        ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
        for (int i = 0; i < list.size(); i++) {
            Student s = list.get(i);
            System.out.println(s.getName() + "‐‐" + s.getAge());
        }
    }

    private static void serializ(ArrayList<Student> arrayList) throws Exception {
        // 创建 序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));
        // 写出对象
        oos.writeObject(arrayList);
        // 释放资源
        oos.close();
    }

四、打印流PrintStream

1.介绍

作用:用来打印各种数据类型

特点:

         a.永远不会抛出IOException

         b.不需要关心字符字节,打印什么就是什么

2. 构造方法

public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流。

PrintStream(OutputStream out): 创建一个新的打印流。

PrintStream(File file): 使用指定的文件创建一个新的打印流。

3.小练习:改变打印流向

 // 调用系统的打印流,控制台直接输出97
        System.out.println(97);
        // 创建打印流,指定文件的名称
        PrintStream ps = new PrintStream("ps.txt");
        // 设置系统的打印流流向,输出到ps.txt
        System.setOut(ps);
        // 调用系统的打印流,ps.txt中输出97
        System.out.println(97);

猜你喜欢

转载自blog.csdn.net/fy_java1995/article/details/82226622
今日推荐