readObject 出现异常: java.io.StreamCorruptedException: invalid type code: AC
今天在项目上面遇到了这个问题:
代码背景
有一个类,在向数据库里面写数据,但是他写数据的方式是有缓存的,他在一定的时间里面接受数据存到自己的buffer里面,然后在特定的时间间隔里面写出去。
如果在buffer有数据的时候断开数据库连接,就会将buffer中的对象保存到文件中。然后在下一次往数据库写的时候读出来再写入数据库。
问题:
在使用ObjectInputSream#readObject的时候,出现了 java.io.StreamCorruptedException: invalid type code: AC异常。
分析:
经过一段时间的google,发现是在readObject的时候复用ObjectInputStream会出现该问题:
复现代码:
package ser;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author lijuny
* @date 2020/12/23
*/
public class TestSer {
private static final String PATH = "/Users/lijunyi/workdir/logs/o.obj";
private static void writeFile(List<Student> studentList) throws IOException {
File file = new File(PATH);
if (!file.exists()) {
file.createNewFile();
}
try (FileOutputStream outputStream = new FileOutputStream(file, true)) {
for (Student student : studentList) {
new ObjectOutputStream(outputStream).writeObject(student);
}
}
}
private static Student readStudent(FileInputStream fileInputStream, InputStream in) throws IOException, ClassNotFoundException {
return (Student) new ObjectInputStream(in).readObject();
}
private static List<Student> readFile() throws IOException, ClassNotFoundException {
List<Student> students = new ArrayList<>();
try (FileInputStream fileInputStream = new FileInputStream(new File(PATH));
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
while (inputStream.available() > 0) {
students.add((Student) objectInputStream.readObject());
}
}
return students;
}
private static List<Student> createStudents(String... names) {
List<Student> students = new ArrayList<>(names.length);
for (String name : names) {
students.add(new Student(name));
}
return students;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
List<Student> students_1 = createStudents("A", "B", "D");
writeFile(students_1);
List<Student> students_2 = createStudents("D", "E", "F");
writeFile(students_2);
List<Student> students = readFile();
System.out.println(students);
}
}
Student类:
package ser;
import java.io.Serializable;
/**
*
* @author lijuny
* @date 2020/12/23
*/
public class Student implements Serializable {
private final String name;
public Student(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
执行出现:
Exception in thread "main" java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1601)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at ser.TestSer.readFile(TestSer.java:49)
at ser.TestSer.main(TestSer.java:68)
但是实际上,我编码的时候使用的并不是复用ObjectInputStream,而是每次readObject都创建了ObjectInputStream,应该不会出现这个问题。
后来知道了,此问题出现的原因是,每次outputStream写入数据的时候每个ObjectOutputStream都会将一个header写入到文件中。
ObjectInputStream靠这个header来去读取文件,但是在读到header之后又读取了到了header就会出现这个异常,也就是在一个对象的磁盘空间出现了两个header
最后只能靠检查代码,但是检查代码也没有发现任何异常,只能暂时放下这个问题,可能是写的时候那里出现问题了,但是具体是哪里不知道。
https://stackoverflow.com/questions/2393179/streamcorruptedexception-invalid-type-code-ac

浙公网安备 33010602011771号