【Java】对象序列化与文件的输入输出

序列化对象与还原对象

序列化对象

保存对象主要有两种方式,第一种,序列化对象并写入文件;第二种,将对象写入纯文本文件。
我们主要来看第一种:序列化对象。

//Weapon.java
public class Weapon {
}
//GameCharacter.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class GameCharacter implements Serializable{
    private int power;
    private String type;
    Weapon[] weapons;

    public Weapon getWeapon() {
        return new Weapon();
    }
    public void useWeapon(){

    }
    public void increasePower(){

    }
    public static void main(String[] args){
        GameCharacter characterOne = new GameCharacter();
        GameCharacter characterTwo = new GameCharacter();
        GameCharacter characterThree = new GameCharacter();

        try {
            FileOutputStream fileStream = new FileOutputStream("MyGame.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(characterOne);
            os.writeObject(characterTwo);
            os.writeObject(characterThree);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • ObjectOutputStream调用writeObject方法,将对象转换成可以写入串流的数据
  • FileOutputStream将字节数据写入文件
  • 对象要被序列化,必须实现Serializable接口
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Box{
    private int width;
    private int height;
    public void setWidth(int w){
        width = w;
    }
    public void setHeight(int h){
        height = h;
    }
    public static void main(String[] args){
        Box box = new Box();
        box.setWidth(10);
        box.setHeight(20);

        try {
            FileOutputStream fileStream = new FileOutputStream("myBox.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(box);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
实例1:类没有实现Serializable接口导致其实例对象不能被序列化

在这里插入图片描述
类Box必须实现Serializable接口,其实例对象才能被序列化,就像下面这样,

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Box implements Serializable{
    private int width;
    private int height;
    public void setWidth(int w){
        width = w;
    }
    public void setHeight(int h){
        height = h;
    }
    public static void main(String[] args){
        Box box = new Box();
        box.setWidth(10);
        box.setHeight(20);

        try {
            FileOutputStream fileStream = new FileOutputStream("myBox.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(box);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
实例2:对象的实例属性没有实现Serializable接口导致对象不能被序列化
//Duck.java
public class Duck {
}
//Pond.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Pond implements Serializable {
    private Duck duck = new Duck();
    public static void main(String[] args){
        Pond pond = new Pond();
        try {
            FileOutputStream fileStream = new FileOutputStream("myPond.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(pond);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
类实例对象的实例属性必须实现Serializable接口,该对象才能被序列化,就像下面这样,

//Duck.java
import java.io.Serializable;

public class Duck implements Serializable{
}
实例3:将实例变量标识为transient可跳过被实例化
//Dog.java
public class Dog {
}
//Pond.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Pond implements Serializable {
    private Duck duck = new Duck();
    private Dog dog = new Dog();
    public static void main(String[] args){
        Pond pond = new Pond();
        try {
            FileOutputStream fileStream = new FileOutputStream("myPond.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(pond);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
如果不想让实例变量dog被序列化,可以将其标识为transient,就像下面这样,

//Pond.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Pond implements Serializable {
    private Duck duck = new Duck();
    private transient Dog dog = new Dog();
    public static void main(String[] args){
        Pond pond = new Pond();
        try {
            FileOutputStream fileStream = new FileOutputStream("myPond.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(pond);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
还原对象

还原对象,也就是解序列化。

//GameCharacter.java
import java.io.Serializable;

public class GameCharacter implements Serializable{
    private int power;
    private String type;

    public GameCharacter(int p,String t){
        power = p;
        type = t;
    }
    public int getPower(){
        return power;
    }
    public String getType(){
        return type;
    }
}
//Test.java
import java.io.*;

public class Test {
    public static void main(String[] args){
        GameCharacter one = new GameCharacter(1,"superman");
        GameCharacter two = new GameCharacter(2,"ironman");
        GameCharacter three = new GameCharacter(3,"caption");
        try {
            FileOutputStream fileOs = new FileOutputStream("myGame.ser");
            ObjectOutputStream os = new ObjectOutputStream(fileOs);
            os.writeObject(one);
            os.writeObject(two);
            os.writeObject(three);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            FileInputStream fileIs = new FileInputStream("myGame.ser");
            ObjectInputStream is = new ObjectInputStream(fileIs);
            GameCharacter one_d = (GameCharacter) is.readObject();
            System.out.println(one_d.getType());
            GameCharacter two_d = (GameCharacter) is.readObject();
            System.out.println(two_d.getType());
            GameCharacter three_d = (GameCharacter) is.readObject();
            System.out.println(three_d.getType());
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 对象会被当作字节读入
  • Java虚拟机根据存储的信息找到对象类型并加载该对象类型
  • 加载实例变量的存储值
  • 读取对象的顺序与写入对象的顺序相同
    在这里插入图片描述
  • 静态变量为类中所有实例共享,而不是属于某个对象,因此静态变量不会被序列化

读写文件

将字符串写入文本文件
//Test.java
import java.io.FileWriter;
import java.io.IOException;

public class Test {
    public static void main(String[] args){
        try {
            FileWriter writer = new FileWriter("foo.txt");
            writer.write("hello world");
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

//Test.java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Test {
    public static void main(String[] args){
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter("foo.txt"));
            writer.write("hello world");
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

先将数据写入缓冲区,等缓冲区满了之后一并写入文件,从而减少操作磁盘的次数。

从文本文件中读取字符串
  • 新建文件foo.txt
hello world
have a nice day
  • 读取foo.txt中的字符串
//Test.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class Test {
    public static void main(String[] args){
        File file = new File("foo.txt");
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line = null;
            while((line = reader.readLine())!=null){
                System.out.println(line);
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

  • 解析字符串
//Test.java

public class Test {
    public static void main(String[] args){
        String str = "What is blue + yellow?/green";
        String[] result = str.split("/");
        for(String token:result){
            System.out.println(token);
        }
    }
}
简单示例
Communication/The Cardigans
Black Dog/Led Zeppelin
Dreams/Van Halen
Comfortably Numb/Pink Floyd
Beth/Kiss
不营业的日常/刘若英

以上是歌单SongList.txt中的内容,每行是“歌名/演唱者”,现在读取这份歌单,将所有歌名加入ArrayList中。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;

public class Test{
    ArrayList<String> list = new ArrayList<String>();
    public static void main(String[] args){
        Test test = new Test();
        test.go();
    }
    public void go(){
        getSongs();
        System.out.println(list);
    }
    public void getSongs(){
        File file = new File("SongList.txt");
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line = null;
            while((line=reader.readLine()) != null){
                addSong(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public void addSong(String line){
        String[] tokens = line.split("/");
        list.add(tokens[0]);
    }
}

在这里插入图片描述

小结

序列化对象还原对象
FileOutputStream fileStream = new FileOutputStream(“MyGame.ser”)FileInputStream fileStream = new FileInputStream(“myGame.ser”)
ObjectOutputStream os= new ObjectOutputStream(fileStream)ObjectInputStream is = new ObjectInputStream(fileStream )
os.writeObject(characterOne)GameCharacter one = (GameCharacter) is.readObject()
os.close()is.close()
写入文本文件读取文本文件
BufferedWriter writer = new BufferedWriter(new FileWriter(“foo.txt”))BufferedReader reader = new BufferedReader(new FileReader(file))
writer.write(“hello world”)reader.readLine()
writer.close()reader.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值