You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:48:21