IO流的转换流

目录

​编辑

转换流

利用转换流按照指定字符编码读取

利用转换流按照指定字符编码写出 

将本地文件中的GBK文件。转成UTF-8 

练习

序列化流 

反序列化流 /对象操作输入流

序列化流/反序列化流的细节

练习 


转换流

是字符流和字节流之间的桥梁

字符转换输入流:InputStreamReader
字符转换输出流:0utputStreamWriter 

下面我们来看个例子👇

利用转换流按照指定字符编码读取

这是GBK文件 

 

package convertstream;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class ConvertStreamDemo1 {

    public static void main(String[] args) throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("..\\Myio\\a.txt"),"GBK");
        //读取资源
        int ch;
        while((ch=isr.read())!=-1){
            System.out.print((char)ch);
        }
        //释放资源
        isr.close();
    }
}

 

在jdk11:这种方法被淘汰了

我们用下面的替代方案

package convertstream;


import java.io.FileReader;
import java.io.IOException;

import java.nio.charset.Charset;

public class ConvertStreamDemo1 {

    public static void main(String[] args) throws IOException {
        FileReader fr=new FileReader("..\\Myio\\a.txt", Charset.forName("GBK"));
        //读取资源
        int ch;
        while((ch=fr.read())!=-1){
            System.out.print((char)ch);
        }
        //释放资源
        fr.close();
    }
}

利用转换流按照指定字符编码写出 

package convertstream;

import java.io.FileOutputStream;
import java.io.IOException;

import java.io.OutputStreamWriter;

public class ConvertStreamDemo2 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("..\\Myio\\d.txt"),"GBK");
        //写出数据
        osw.write("你好你好");
        //释放资源
        osw.close();
    }
}

 

 就可以查看写出的数据

下面为替代方法 

package convertstream;


import java.io.FileWriter;
import java.io.IOException;


import java.nio.charset.Charset;

public class ConvertStreamDemo2 {
    public static void main(String[] args) throws IOException {
        FileWriter fw=new FileWriter("..\\Myio\\d.txt", Charset.forName("GBK"));
        //写出数据
        fw.write("你好你好");
        //释放资源
        fw.close();
    }
}

将本地文件中的GBK文件。转成UTF-8 

jdk11以前的方案👇

package convertstream;

import java.io.*;

public class ConvertStreamDemo3 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("..\\Myio\\a.txt"),"GBK");
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("..\\Myio\\d.txt"),"UTF-8");
        int a;
        while ((a=isr.read())!=-1){
            osw.write(a);
        }
        //释放资源
        osw.close();
        isr.close();
    }
}

 

替代方案👇 

package convertstream;

import java.io.*;
import java.nio.charset.Charset;

public class ConvertStreamDemo3 {
    public static void main(String[] args) throws IOException {
        
        FileReader fr=new FileReader("..\\Myio\\a.txt", Charset.forName("GBK"));
        FileWriter fw=new FileWriter("..\\Myio\\d.txt",Charset.forName("UTF-8"));
        int a;
        while ((a=fr.read())!=-1){
            fw.write(a);
        }
        //释放资源
        fw.close();
        fr.close();
    }
}

运行结果都是一样的

练习

利用字节流读取文件中的数据,每次读一整行,面且不能出现乱码

package convertstream;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class ConvertStreamDemo4 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("..\\Myio\\d.txt"));
        BufferedReader br=new BufferedReader(isr);
        String line;
        while((line=br.readLine())!=null) {
            System.out.println(line);
        }
        br.close();
    }
}

还可以给创建对象的合并在一起👇

序列化流 

序列化流/对象操作输出流

可以把Java中的对象写到本地文件中

构造方法:
public objectoutputstream(outputstream out)        把基本流包装成高级流

成员方法:
public final void writeobject(object obj)                把对象序列化(写出)到文件中去

利用序列化流/对象操作输出流,把一个对象写到本地文件中👇

先写Student类

package objectstream;



public class Student {
    private String name;
    private Integer age;

    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

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

 再写测试类

package objectstream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //创建学生对象
        Student stu=new Student("张三",18);
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\Myio\\a.txt"));
        //写出数据    
        oos.writeObject(stu);
        //释放资源
        oos.close();
    }
}

 使用对象输出流将对象保存到文件时会出现NotserializableException异常

解决方案:需要让Javabean类实现Serializable接口 

Serializable接口里面是没有抽象方法,标记型接口

一旦实现了这个接口,那么就表示当前的student类可以被序列化

修改后的Student类:

package objectstream;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private Integer age;

    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

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

反序列化流 /对象操作输入流

可以把序列化到本地文件中的对象,读取到程序中来 

构造方法
public objectInputstream(Inputstream out)                把基本流变成高级流

成员方法
public object readobject()                把序列化到本地文件中的对象,读取到程序中来

package objectstream;

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

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

 

序列化流/反序列化流的细节

先序列化流将数据写到本地文件当中 

如果现在在Student类里加上👇

这个时候运行反序列化流就会出现报错

文件中的版本号,跟lavabean的版本号不匹配

我们可以复制Serializable,在setting里粘贴进去

勾选标红线的两个,再Apply->OK

 再回到Student中,贯标放到Student上Alt+回车,让idea帮我们添加

这个时候再执行一遍上述的添加address的操作,也就不会报错 

如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

重新写一下Student类

package objectstream;



import java.io.Serial;
import java.io.Serializable;

public class Student implements Serializable {


    @Serial
    private static final long serialVersionUID = 348569226864978244L;
    private String name;
    private Integer age;
    private String address;


    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * 获取
     * @return address
     */
    public String getAddress() {
        return address;
    }

    /**
     * 设置
     * @param address
     */
    public void setAddress(String address) {
        this.address = address;
    }

    public String toString() {
        return "Student{" + serialVersionUID + ", name = " + name + ", age = " + age + ", address = " + address + "}";
    }
}

这个时候我不想序列化address

可以在前面加上transient关键字

 这个时候执行一遍

address不参与序列化

  • 使用序列化流将对象写到文件时,需要让Javabean类实现Serializable接口,否则,会出现NotSerializableException异常
  • 序列化流写到文件中的数据是不能修改的,一旦修改就无法再次读回来了
  • 序列化对象后,修改了Javabean类,再次反序列化,会不会有问题?会出问题,会抛出InvalidclassException异常解决方案:给Javabean类添加serialVersionUID(列号、版本号)
  • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

                解决方案:给该成员变量加transient关键字修饰该关键字标记的成员变量不参与序列化过程

练习 

将多个自定义对象序列化到文件中。但是对象的个数不确定,该如何操作呢?

Student类

package convertstream;

import java.io.Serial;
import java.io.Serializable;

public class Student implements Serializable {
    @Serial
    private static final long serialVersionUID = 3771817918770415923L;
    private String name;
    private Integer age;

    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

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

序列化流:

package convertstream;

import java.io.*;
import java.util.ArrayList;

public class ConvertStreamTest1 {
    public static void main(String[] args) throws IOException {
        Student s1=new Student("张三",18);
        Student s2=new Student("李四",20);
        Student s3=new Student("王五",19);
        ArrayList<Student>list=new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\Myio\\a.txt"));
        oos.writeObject(list);
        oos.close();
    }
}

 反序列化流

package convertstream;

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

public class ConvertStreamTest2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("..\\Myio\\a.txt"));
        ArrayList<Student>list = (ArrayList<Student>)ois.readObject();
        for (Student student : list) {
            System.out.println(student);
        }
        ois.close();
    }
}


转换流与序列化流就说到这里啦

努力遇见更好的自己!!!

 

相关推荐

  1. IO转换

    2024-06-12 08:44:08       9 阅读
  2. IO——其他

    2024-06-12 08:44:08       18 阅读
  3. IO-字符

    2024-06-12 08:44:08       11 阅读
  4. IO(字符)

    2024-06-12 08:44:08       7 阅读
  5. IO

    2024-06-12 08:44:08       44 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-12 08:44:08       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-12 08:44:08       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-12 08:44:08       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-12 08:44:08       18 阅读

热门阅读

  1. ubuntu22.04禁止自动休眠的几种方式

    2024-06-12 08:44:08       9 阅读
  2. 算法训练营day53

    2024-06-12 08:44:08       7 阅读
  3. 代码随想录算法训练营day44

    2024-06-12 08:44:08       8 阅读
  4. 【环境搭建】3.阿里云ECS服务器 安装Redis

    2024-06-12 08:44:08       7 阅读
  5. CDN、CNAME、DNS

    2024-06-12 08:44:08       6 阅读
  6. php框架详解-symfony框架

    2024-06-12 08:44:08       7 阅读