Java面向对象之对象流、标准输入输出流及转换流-InputStreamReader 和 OutputStreamWriter

1、对象流

1.1、定义

功能:提供了对基本类型或对象类型的序列化和反序列化的方法
ObjectOutputStream 提供 序列化功能
ObjectInputStream 提供 反序列化功能

1.2、一览图

在这里插入图片描述

1.3、应用案例 1

使用ObjectOutStream 序列化基本数据类型和一个Dog对象(name,age),并保存到data.dat文件中

ObjectOutStream_.java

package outputstream_;

import java.io.*;

/**
 * ObjectOutputStream 的使用, 完成数据的序列化
 */
public class ObjectOutStream_ {
    public static void main(String[] args) throws IOException {
        // 序列化后, 保存的文件格式, 不是存文本, 而是按照他的格式来保存
        String filePath = "e:\\data.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
        // 序列化数据到 e:\data.dat
        oos.writeInt(100);  // int -> Integer (实现了 Serializable)
        oos.writeBoolean(true);  // boolean -> Boolean (实现了 Serializable)
        oos.writeChar('a');  // char -> Character (实现了 Serializable)
        oos.writeDouble(9.5);  // double -> Double (实现了 Serializable)
        oos.writeUTF("你好世界");  // String
        // 保存一个 dog 对象
        oos.writeObject(new Dog("旺财", 10, "日本", "白色"));
        oos.close();
        System.out.println("数据保存完毕(序列化形式)");
    }
}

Dog.java

package outputstream_;

import java.io.Serializable;

public class Dog implements Serializable {
    private String name;
    private int age;
    private String area;
    private String color;

    public Dog(String name, int age, String area, String color) {
        this.name = name;
        this.age = age;
        this.area = area;
        this.color = color;
    }

    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 String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}
1.4、应用案例 2

使用ObjectInputStream 读取 data.dat 并反序列化恢复数据

package inputstream_;

import outputstream_.Dog;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //指定反序列化的文件
        String filePath = "e:\\data.dat";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        // 读取
        // 1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
        // 2. 否则会出现异常
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());

        // dog 的编译类型是 Object, dog 的运行类型是 Dog
        Object dog = ois.readObject();
        System.out.println("运行类型=" + dog.getClass());
        System.out.println("dog信息=" + dog);  // 底层 Object -> Dog

        // 这里是特别重要的细节:
        // 1. 如果我们希望调用Dog的方法, 需要向下转型
        // 2. 需要我们将Dog类的定义, 放在到可以引用的位置
        Dog dog2 = (Dog) dog;
        System.out.println(dog2.getName()); //旺财..

        // 关闭流, 关闭外层流即可, 底层会关闭 FileInputStream 流
        ois.close();
    }
}

控制台输出

100
true
a
9.5
你好世界
运行类型=class outputstream_.Dog
dog信息=outputstream_.Dog@70177ecd
旺财
1.5、注意事项和细节说明

在这里插入图片描述

2、标准输入输出流

在这里插入图片描述
在这里插入图片描述

package standard;

import java.util.Scanner;

public class InputAndOutput {
    public static void main(String[] args) {
        // System 类 的 public final static InputStream in = null;
        // System.in 编译类型   InputStream
        // System.in 运行类型   BufferedInputStream
        // 表示的是标准输入 键盘
        System.out.println(System.in.getClass());  // class java.io.BufferedInputStream

        // 解读
        // 1. System.out public final static PrintStream out = null;
        // 2. 编译类型 PrintStream
        // 3. 运行类型 PrintStream
        // 4. 表示标准输出 显示器
        System.out.println(System.out.getClass());  // class java.io.PrintStream
        System.out.println("hello, world");
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入内容");
        String next = scanner.next();
        System.out.println("next=" + next);
    }
}

3、转换流-InputStreamReader 和 OutputStreamWriter

3.1、引出问题

先看一个文件乱码问题,引出学习转换流必要性

package transformation;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * 看一个中文乱码问题
 */
public class CodeQuestion {
    public static void main(String[] args) throws IOException {
        // 读取 e:\\a.txt 文件到程序
        // 思路
        // 1. 创建字符输入流 BufferedReader [处理流]
        // 2. 使用 BufferedReader 对象读取 a.txt
        // 3. 默认情况下, 读取文件是按照 utf-8 编码
        String filePath = "e:\\a.txt";
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        String s = br.readLine();
        System.out.println("读取到的内容: " + s);
        br.close();
        // InputStreamReader
        // OutputStreamWriter
    }
}

在这里插入图片描述

3.2、定义

在这里插入图片描述

3.3、应用案例 1

编程将字节流 FileInputStream 包装成(转换成)字符流InputStreamReader,对文件进行读取(按照 utf-8/gbk 格式),进而在包装成 BufferedReader

package transformation;

import java.io.*;

/**
 * 使用 InputStreamReader 转换流解决中文乱码问题
 * 将字节流 FileInputStream 转成字符流 InputStreamReader, 指定编码 gbk/utf-8
 */
public class InputStreamReader_ {
    public static void main(String[] args) throws IOException {
        String filePath = "e:\\a.txt";
        // 解读
        // 1. 把 FileInputStream 转成 InputStreamReader
        // 2. 指定编码 gbk
        // InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
        // 3. 把 InputStreamReader 传入 BufferedReader
        // BufferedReader br = new BufferedReader(isr);
        // 将 2 和 3 合在一起
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));
        // 4. 读取
        String s = br.readLine();
        System.out.println("读取内容=" + s);
        // 5. 关闭外层流
        br.close();
    }
}
3.4、应用案例 2

将字节流 FileOutputStream 包装成(转换成)字符流OutputStreamWriter,对文件进行写入(按照gbk格式,可以指定其他,比如 utf-8)

package transformation;

import java.io.*;

/**
 * OutputStreamWriter 使用
 * 把FileOutputStream 字节流, 转成字符流 OutputStreamWriter
 * 指定处理的编码 gbk/utf-8/utf8
 */
public class OutputStreamWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "e:\\test.txt";
        String charSet = "utf-8";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
        osw.write("hi, 张三");
        osw.close();
        System.out.println("按照 " + charSet + " 保存文件成功~");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值