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
相关产品推荐
相关产品推荐

