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

读取DataInputStream时遭遇EOFException问题求助

问题根源

你的代码出现EOFException的核心原因是读写数据的格式完全不匹配:

  • 写入时,所有数据(包括账号数字、余额)都通过writeUTF()以字符串形式写入文件;
  • 读取时却试图用readInt()、readDouble()读取对应类型的二进制数据,这会导致读取解析错误,很快触发文件末尾异常。
    另外,read.available()不能可靠判断文件是否还有未读取数据,这个方法仅返回当前输入流中可立即读取的字节数,不能作为循环终止条件。
解决方案

提供两种修复方式,选其一即可:

方案一:修改写入代码,匹配读取的类型

将写入时的字符串转换操作去掉,直接用对应类型的写入方法:

try {
    Scanner input = new Scanner(new File("accounts.txt"));
    int index = 0;
    int accNum = 0;
    String accName = "";
    double balance = 0;
    String accType = "";

    ArrayList<Account> accounts = new ArrayList<>();

    while (input.hasNextLine()) {
        if (index == 0) {
            accNum = Integer.parseInt(input.nextLine());
            index++;
        } else if (index == 1) {
            accName = input.nextLine();
            index++;
        } else if (index == 2) {
            accType = input.nextLine();
            index++;
        } else if (index == 3) {
            balance = Double.parseDouble(input.nextLine());

            accounts.add(new Account(accNum, accName, balance, accType));
            index = 0;
        }
    }

    input.close();

    try (FileOutputStream accountTxtFile = new FileOutputStream("accounts.bin");
         DataOutputStream accountBinFile = new DataOutputStream(accountTxtFile)) {

        for (Account accountObj : accounts) {
            accountBinFile.writeInt(accountObj.getAccountNumber());
            accountBinFile.writeUTF(accountObj.getAccountHolderName());
            accountBinFile.writeUTF(accountObj.getAccountType());
            accountBinFile.writeDouble(accountObj.getBalance());

            // 验证输出
            System.out.println(accountObj.getAccountNumber());
            System.out.println(accountObj.getAccountHolderName());
            System.out.println(accountObj.getAccountType());
            System.out.println(accountObj.getBalance());
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

同时修改读取代码,用try-catch捕获EOFException作为循环结束标志(替代不可靠的available()):

try (DataInputStream read = new DataInputStream(new FileInputStream("accounts.bin"))) {
    while (true) {
        try {
            int accNum = read.readInt();
            String accName = read.readUTF();
            String accType = read.readUTF();
            double balance = read.readDouble();

            System.out.println(accNum + " " + accName + " " + accType + " " + balance);
        } catch (EOFException e) {
            // 读取到文件末尾,正常退出
            break;
        }
    }
} catch (IOException e) {
    System.err.println("文件操作出错");
    e.printStackTrace();
}

方案二:修改读取代码,匹配写入的格式

如果不想改动写入逻辑,就统一用readUTF()读取所有数据,再转换为对应类型:

try (DataInputStream read = new DataInputStream(new FileInputStream("accounts.bin"))) {
    while (true) {
        try {
            String accNumStr = read.readUTF();
            String accName = read.readUTF();
            String accType = read.readUTF();
            String balanceStr = read.readUTF();
            
            int accNum = Integer.parseInt(accNumStr);
            double balance = Double.parseDouble(balanceStr);

            System.out.println(accNum + " " + accName + " " + accType + " " + balance);
        } catch (EOFException e) {
            // 读取到末尾,退出循环
            break;
        } catch (NumberFormatException e) {
            System.err.println("数据格式转换失败");
            e.printStackTrace();
        }
    }
} catch (IOException e) {
    System.err.println("文件操作出错");
    e.printStackTrace();
}
额外注意
  • 优先使用try-with-resources语法(如上述代码),它会自动关闭流,避免资源泄漏;
  • 不要依赖available()判断文件是否读完,这种方式在网络流或缓冲流场景下完全不可靠,捕获EOFException是更稳妥的方式。

内容的提问来源于stack exchange,提问作者gangrx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:50:23