文章目录
- 序列化对象与还原对象
- 序列化对象
- 实例1:类没有实现Serializable接口导致其实例对象不能被序列化
- 实例2:对象的实例属性没有实现Serializable接口导致对象不能被序列化
- 实例3:将实例变量标识为transient可跳过被实例化
- 还原对象
- 读写文件
- 将字符串写入文本文件
- 从文本文件中读取字符串
- 简单示例
- 小结
序列化对象与还原对象
序列化对象
保存对象主要有两种方式,第一种,序列化对象并写入文件;第二种,将对象写入纯文本文件。
我们主要来看第一种:序列化对象。
//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() |