Java报错java.io.StreamCorruptedException: invalid type code: AC求助
问题原因
你遇到的java.io.StreamCorruptedException: invalid type code: AC错误,核心原因是追加写入对象流时重复创建了ObjectOutputStream:
- 每次调用
new ObjectOutputStream(fos)时,都会向文件中写入一段对象流的头部信息(包含魔数、版本号等) - 读取时,
ObjectInputStream读完第一个对象后,下一个读取到的是新的流头部而非预期的Student对象,因此抛出格式错误。
另外注意:你代码里的路径字符串"C:\code..."存在语法问题,Java中路径分隔符需要转义为\\,否则会被识别为无效转义字符。
解决办法
方法1:一次性写入所有对象(推荐)
如果是批量写入学生对象,建议把所有Student放到集合中一次性写入,读取时直接读取整个集合,避免追加带来的流头部冲突:
写入代码修改:
import java.util.ArrayList; import java.util.List; import java.io.*; // 示例:批量写入学生对象 List<Student> studentList = new ArrayList<>(); studentList.add(new Student("张三")); studentList.add(new Student("李四")); // 使用try-with-resources自动关闭流 try (FileOutputStream fos = new FileOutputStream("C:\\code\\java\\asignment\\Student\\ListStudent2.dat"); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(studentList); } catch (IOException e) { e.printStackTrace(); }
读取代码修改:
import java.util.List; import java.io.*; try (FileInputStream fis = new FileInputStream("C:\\code\\java\\asignment\\Student\\ListStudent2.dat"); ObjectInputStream ois = new ObjectInputStream(fis)) { @SuppressWarnings("unchecked") List<Student> studentList = (List<Student>) ois.readObject(); for (Student t : studentList) { System.out.println(t.getName()); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
方法2:实现可追加的对象流(适合多次追加写入场景)
如果必须分多次追加写入,不能每次新建ObjectOutputStream,可以通过跳过重复头部的方式实现:
import java.io.*; FileOutputStream fos = new FileOutputStream("C:\\code\\java\\asignment\\Student\\ListStudent2.dat", true); ObjectOutputStream oos; // 判断文件是否为空,第一次写入正常创建流,后续写入跳过头部 if (fos.getChannel().size() == 0) { oos = new ObjectOutputStream(fos); } else { oos = new ObjectOutputStream(fos) { @Override protected void writeStreamHeader() throws IOException { reset(); // 不写入新的流头部 } }; } // 写入单个对象 oos.writeObject(new Student("王五")); oos.flush(); // 所有写入完成后关闭流 oos.close(); fos.close();
对应的读取代码可以保持你原来的循环逻辑,只需修正路径并捕获EOFException退出循环:
import java.io.*; try (FileInputStream fis = new FileInputStream("C:\\code\\java\\asignment\\Student\\ListStudent2.dat"); ObjectInputStream ois = new ObjectInputStream(fis)) { while (true) { try { Student t = (Student) ois.readObject(); System.out.println(t.getName()); } catch (EOFException e) { // 读取到文件末尾,退出循环 break; } } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
注意事项
- 确保
Student类的所有成员变量(包括引用类型)都实现了Serializable接口 - 优先使用try-with-resources语法,避免手动关闭流时出现资源泄漏
- 追加写入场景下,尽量避免频繁创建
ObjectOutputStream,否则会持续写入无效的流头部
内容的提问来源于stack exchange,提问作者Nguyễn Anh Đức
相关产品推荐
相关产品推荐

