在写实践项目二时,要把对象信息存放在文件里,所以用到了序列化,我习惯先把对象先创建好,之后方便调用,但是在创建序列化对象时遇到了问题。下面是我根据遇到的问题,写的相关代码。
有问题的代码
package PrintStream;
import game.TSUtility;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException{
//这行代码,本身没有问题
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Phase eight\\javase.txt"));
System.out.println("请输入名字:");
String name = TSUtility.readKeyBoard(4, false);
System.out.println("请输入年龄:");
int age = TSUtility.readInt();
if (age>100){
System.exit(0);
}
else {
Student s = new Student(name, age);
ArrayList<Student> arrayList=new ArrayList<>();
arrayList.add(s);
oos.writeObject(arrayList);
oos.close();
}
}
}
可以看见,我在一开始就创建好对象,年龄大于100,java虚拟机会结束程序,按我当时的想法时不会将集合序列化,添加到文件,但是结果是在文件里写了一点东西,我不知道是什么,结果如下
可以看见年龄120,程序结束,但是文件里写了东西,当我反序列化,读文件里的东西时,报错
反序列化代码
package PrintStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("Phase eight\\javase.txt"));
ArrayList arrayList=new ArrayList<>();
Object o = ois.readObject();
arrayList=(ArrayList)o;
for (Object s:arrayList){
System.out.println(s);
}
ois.close();
}
}
运行结果
我的理解就是,创建序列化ObjectOutputStream对象时,会在文件开头写一个默认字节码标识,ObjectIutputStream读文件时,会根据这个标识来读,但是我们并没有写入东西在文件里,所以抛出异常
我开始的解决办法,就是要用到序列化对象时再创建
代码如下
package PrintStream;
import game.TSUtility;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
System.out.println("请输入名字:");
String name = TSUtility.readKeyBoard(4, false);
System.out.println("请输入年龄:");
int age = TSUtility.readInt();
try {
if (age > 100) {
throw new RuntimeException("输入年龄不正常");
} else {
//放到这里
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Phase eight\\javase.txt"));
Student s = new Student(name, age);
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(s);
oos.writeObject(arrayList);
oos.close();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
结果如下
可以看见文件里没有写入开始的标识,因为本身没有运行到创建对象那里就抛出异常了
还有一种方法,是在文件里已经写了标识之后,在读文件之前判断一下
还是先把对象创建了
文件里有标识
读之前判断
package PrintStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("Phase eight\\javase.txt"));
ArrayList arrayList=new ArrayList<>();
if(ois.available()>0){
Object o = ois.readObject();
arrayList=(ArrayList)o;
for (Object s:arrayList){
System.out.println(s);
}
}else{
System.out.println("没有数据");
}
ois.close();
}
}
结果如下
其中ois.available 是返回文件中的内容。