转换流/序列化/反序列化

转换流:

使用转换流可以在一定程度上避免乱码,还可以指定输入输出所使用的字符集
InputStreamReader:是从字节流到字符流的桥梁,父类是Reader
OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer

转换流图解:
在这里插入图片描述
转换流的构造方法:

方法名说明
InputStreamReader(InputStream in)使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset)使用指定的字符编码创建InputStreamReader对象
OutputStreamWriter(OutputStream out)使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset)使用指定的字符编码创建OutputStreamWriter对象
    public static void main(String[] args) throws IOException {
        // JDK11前的方法
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/b.txt"));
        InputStreamReader isr = new InputStreamReader(new FileInputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt"), "UTF-8");
        // JDK11后子字符流推出了新的构造方法
        FileReader fr = new FileReader("/Users/itzhuzhu/Desktop/Java/ideaTest/io/a.txt", Charset.forName("gbk"));
        char[] chars = new char[1024];
        int len;
        while ((len = isr.read(chars)) != -1) {
            osw.write(chars, 0, len);
        }
        osw.close();
        isr.close();
    }
对象操作流:

对象序列化:

将Java中的对象保存到文件中

  • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
  • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
  • 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
  • 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

构造方法

方法名说明
ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法

方法名说明
void writeObject(Object obj)将指定的对象写入ObjectOutputStream

对象反序列化:

将文件中的对象,加载到程序中

构造方法

方法名说明
ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法

方法名说明
Object readObject()从ObjectInputStream读取一个对象

serialVersionUID:

序列化了一个对象后修改了对象再去读就会异常(InvalidClassException)
解决:给对象所属的类加一个serialVersionUID ,值随便定,不超Long就行

transient:

如果一个对象中的某个成员变量的值不想被序列化,就给成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
static: 被这个关键字修饰的成员变量在序列化时不会保存到文件中

-1&null的使用场景:

while ((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); }

read():读取到文件末尾返回值是 ‐1

readLine():读取到文件的末尾返回值 null

readObject():读取到文件的末尾 直接抛出异常(把序列化的对象存储到集合中,把集合序列化到文件中)

代码演示:

// 把某个对象序列化就要把对象实现Serializable接口,但是不需要重写,因为Serializable没有方法,就是标记性接口
public class Student implements Serializable {
    public static final long serialVersionUID = 1L;
    private String username;
    private transient String password;

    public Student() {
    }

    public Student(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

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

测试类:

public class Demo02 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // write();
        // read();
        readArray();
    }

    //反序列化
    private static void read() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/b.txt"));
        Object obj = ois.readObject();
        Student s = (Student) obj;
        System.out.println(s);
        ois.close();
    }

    //序列化
    private static void write() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/b.txt"));
        Student s = new Student("itzhuzhu", "12345");
        oos.writeObject(s);
        oos.close();
    }

    //反序列化读取多个对象
    private static void readArray() throws IOException, ClassNotFoundException {
        Student s1 = new Student("韩信", "hanxin");
        Student s2 = new Student("李白", "libai");
        Student s3 = new Student("露娜", "luna");
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);

        // 创建序列化对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/b.txt"));
        // 把对象装到集合再存到文件
        oos.writeObject(list);
        oos.close();

        // 创建反序列化对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/itzhuzhu/Desktop/Java/ideaTest/io/b.txt"));
        // 把文件里的对象数据读取到内存
        ArrayList<Student> list2 = (ArrayList<Student>) ois.readObject();
        for (Student student : list2) {
            System.out.println(student);
        }
        ois.close();
    }
}
打印流:

打印流分类:

字节打印流: PrintStream 字符打印流: PrintWriter

打印流的特点:

只有输出方向 让内容原样输出

构造方法:

  • PrintStream​(String fileName) 通过路径名字符串创建打印流
  • PrintStream​(File file) 通过File对象创建打印流
  • PrintStream​(OutputStream out) 通过OutputStream创建打印流

普通方法:

  • void print​(Xxx x) 打印后不换行
  • void println​(Xxx x) 打印后换行
public static void main(String[] args) throws FileNotFoundException {
        // test01();

        // out是System类中的一个静态成员变量,什么类型呢?PrintStream字节打印流
        // 我们可以修改out的流向
        System.out.println(65);
        System.out.println("你好");

        // 自己创建一个新的字节打印流
        PrintStream ps = new PrintStream("day10demo\\abc\\oo.txt");
        System.setOut(ps);

        System.out.println("97");
        System.out.println("大家好");
    }

    private static void test01() throws FileNotFoundException {
        // 创建打印流
        PrintStream ps = new PrintStream("day10demo\\abc\\ps.txt");
        
        // 打印数据
        ps.println(110);
        ps.println(36.0d);
        ps.println('好');
        ps.println(true);
        ps.println("真的好");

        // 关闭流
        ps.close();
    }
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzhuzhu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值