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

Java等待JSON的updated属性变为true时遇EOF异常,求解决方案

问题原因

你遇到的Unexpected token END OF FILE异常,本质是竞态条件:Python脚本在写入JSON文件的过程中(比如正在清空旧内容、还没写完新内容),Java程序频繁读取文件,此时文件内容不完整甚至为空,导致JSON解析器无法正常解析。

可行解决方案

1. 增加轮询延迟+异常捕获

在循环中添加休眠时间降低读取频率,同时捕获解析异常避免程序崩溃:

Runtime.getRuntime().exec("python3 src/main/java/metis.py");
boolean pythonExecuted = false;
String jsonPath = String.valueOf(Paths.get("./json/", "output.json"));
JSONParser jsonParser = new JSONParser();

while (!pythonExecuted) {
    try (FileReader reader = new FileReader(jsonPath)) { // 自动关闭流
        JSONObject obj = (JSONObject) jsonParser.parse(reader);
        boolean updated = (boolean) obj.get("updated");
        if (updated) {
            pythonExecuted = true;
        }
    } catch (Exception e) {
        // 解析失败时跳过本次循环,继续等待
    }
    // 每次循环休眠500ms,可根据实际情况调整
    try {
        Thread.sleep(500);
    } catch (InterruptedException ie) {
        Thread.currentThread().interrupt();
        break;
    }
}

2. 等待Python进程执行完毕(适用于一次性脚本)

如果你的Python脚本是更新完JSON文件就退出,可以直接等待进程结束后再读取文件,从根源避免竞态:

Process pythonProcess = Runtime.getRuntime().exec("python3 src/main/java/metis.py");
// 阻塞等待Python进程执行完成
pythonProcess.waitFor();

// 进程结束后读取JSON文件
String jsonPath = String.valueOf(Paths.get("./json/", "output.json"));
JSONParser jsonParser = new JSONParser();
try (FileReader reader = new FileReader(jsonPath)) {
    JSONObject obj = (JSONObject) jsonParser.parse(reader);
    boolean updated = (boolean) obj.get("updated");
    // 后续业务逻辑
}

3. 使用进程间通信替代文件轮询

文件轮询效率低且易出问题,更可靠的方式是让Python主动通知Java任务完成:

方式A:标准输出传递信号

Java代码:

Process pythonProcess = Runtime.getRuntime().exec("python3 src/main/java/metis.py");
BufferedReader outputReader = new BufferedReader(new InputStreamReader(pythonProcess.getInputStream()));

// 等待Python发送完成信号
String line;
while ((line = outputReader.readLine()) != null) {
    if ("TASK_DONE".equals(line)) {
        // 读取JSON文件
        String jsonPath = String.valueOf(Paths.get("./json/", "output.json"));
        JSONParser jsonParser = new JSONParser();
        try (FileReader reader = new FileReader(jsonPath)) {
            JSONObject obj = (JSONObject) jsonParser.parse(reader);
            // 后续逻辑
        }
        break;
    }
}

pythonProcess.waitFor();
outputReader.close();

Python脚本末尾添加:

# 完成JSON更新后发送信号
print("TASK_DONE")

方式B:本地Socket通信

Python更新完文件后向本地Socket发送消息,Java监听该Socket,收到消息后读取文件。这种方式适合复杂交互场景。

4. 文件锁实现读写互斥

在Python写入文件时加独占锁,Java读取前检查锁状态,确保文件写入完成后再读取:

  • Python端:Linux/macOS用fcntl,Windows用msvcrt加锁
  • Java端:用FileChannel尝试获取共享锁,成功后再读取文件

该方式实现稍复杂,但能严格避免读写冲突。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:25:26