Java中将多值文件加载至ArrayList时出现StreamCorruptedException问题求助
解决java.io.StreamCorruptedException: invalid stream header错误
嘿,这个错误的根源很清晰——你用错了文件读取工具!
你现在的文件是普通的文本格式,每行都是accountNumber=xxx这样的键值对,但你却用了ObjectInputStream来读取它。这个类是专门用来读取Java序列化后的二进制对象的,它一开头就会去寻找序列化对象特有的二进制头部,结果读到的却是文本的"acco"(错误里的6163636F就是"acco"的ASCII码),自然就抛出了流头部无效的错误。
下面分两种情况给你解决方案:
情况1:你就是想读取这个文本格式的文件
那你需要用读取文本的工具类,比如BufferedReader,逐行读取后解析内容到Account对象里。这里给你写个完整的示例:
// 先确保你的Account类有对应的getter/setter方法 private static ArrayList<Account> accounts = new ArrayList<>(); // 全局静态变量 private static void loadAccounts() throws IOException { try (BufferedReader br = new BufferedReader(new FileReader("AccountFile"))) { String line; // 逐行读取文件内容 while ((line = br.readLine()) != null) { Account account = new Account(); // 按逗号分割每个键值对,同时忽略逗号后的空格 String[] keyValuePairs = line.split(",\\s*"); for (String pair : keyValuePairs) { // 分割键和值 String[] parts = pair.split("="); String key = parts[0].trim(); String value = parts[1].trim(); // 根据键设置Account的属性,注意去掉branchName的单引号 switch (key) { case "accountNumber": account.setAccountNumber(Integer.parseInt(value)); break; case "branchName": account.setBranchName(value.replace("'", "")); break; case "balance": account.setBalance(Integer.parseInt(value)); break; case "customerNumber": account.setCustomerNumber(Integer.parseInt(value)); break; } } accounts.add(account); } } }
这段代码会逐行解析你的文本文件,把每一行的内容封装成Account对象,再加入到ArrayList里。
情况2:你原本想使用Java序列化(存储对象而非文本)
如果你的初衷是把ArrayList<Account>序列化到文件里,那你之前的写入步骤完全错误——你手动写了文本,而不是用ObjectOutputStream来序列化对象。
首先,你的Account类必须实现Serializable接口(否则无法被序列化):
import java.io.Serializable; public class Account implements Serializable { // 类的属性 private int accountNumber; private String branchName; private int balance; private int customerNumber; // 构造方法、getter和setter方法 public Account() {} public void setAccountNumber(int accountNumber) { this.accountNumber = accountNumber; } // 其他getter/setter同理... }
然后,正确的序列化写入方法应该是这样的:
private static void saveAccounts(ArrayList<Account> accounts) throws IOException { // 使用try-with-resources自动关闭流 try (FileOutputStream fos = new FileOutputStream("AccountFile"); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(accounts); } }
最后,修正你原来的loadAccounts方法(注意:方法内部不能定义静态变量,把accounts改成全局静态变量):
private static ArrayList<Account> accounts = new ArrayList<>(); private static void loadAccounts() throws IOException, ClassNotFoundException { try (FileInputStream fileInputStream = new FileInputStream("AccountFile"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) { accounts = (ArrayList<Account>) objectInputStream.readObject(); } }
这样修改后,当你先调用saveAccounts把对象序列化到文件,再调用loadAccounts读取,就不会报错了。
内容的提问来源于stack exchange,提问作者Sajjad Serajzadeh
相关产品推荐
相关产品推荐

