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

Java使用JSONObject写入JSON文件覆盖旧数据未追加如何解决

问题根因

代码无法实现追加、原有数据被覆盖,是几个核心问题导致的:

  • 每次读取完原有JSON的根节点后,直接执行root.put("system", idJson),会用全新创建的空idJson对象完全替换掉文件中原本存在的system节点,之前写入的所有id条目会被直接清空
  • 写入id节点时错误使用了固定字符串"id"作为键,没有使用遍历得到的动态id变量作为键,即便不覆盖system节点,也只会反复修改同一个固定字段,无法生成id1、id2这类并列的节点结构
  • 原代码对FileWriter没有做异常安全的关闭处理,写入过程如果抛出异常,会导致文件损坏、流资源泄漏
  • 额外的编译问题:如果数据源是List<List<String>>类型,原代码用数组下标语法list[i][0]访问元素会直接编译失败,List类型需要调用get()方法取值
修复方案

调整核心处理逻辑:

  1. 读取目标文件的JSON内容后,先取出已经存在的system节点对象,如果节点不存在再新建空的JSONObject,不要直接替换整个system节点
  2. 往取出的已有system节点中,以当前遍历到的id变量为键,放入对应的value对象,实现追加效果
  3. 用try-with-resources语法自动管理文件写入流,保证异常场景下流也能被正常关闭
  4. 补充空数据、文件不存在的边界场景判断,避免运行时异常

修复后的可运行代码示例:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONObject;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class JsonWriteUtil {
    // 提前初始化ObjectMapper,全局复用避免重复创建开销
    private static final ObjectMapper mapper = new ObjectMapper();
    // 替换为你实际的全局list数据源
    private static List<List<String>> list;

    public static void writeInJsonFile() throws IOException {
        for (int i = 0; i < list.size(); ++i) {
            List<String> currentRow = list.get(i);
            // 跳过元素不足的无效数据行
            if (currentRow == null || currentRow.size() < 3) {
                continue;
            }
            String path = currentRow.get(0);
            String value = currentRow.get(1);
            String id = currentRow.get(2);

            File targetFile = new File(path);
            JSONObject root;
            // 文件不存在或为空时初始化空根节点
            if (targetFile.exists() && targetFile.length() > 0) {
                root = mapper.readValue(targetFile, JSONObject.class);
            } else {
                root = new JSONObject();
            }

            // 获取已存在的system节点,不存在则新建
            JSONObject systemNode = root.optJSONObject("system");
            if (systemNode == null) {
                systemNode = new JSONObject();
                root.put("system", systemNode);
            }

            // 往现有system节点追加当前id对应的内容,不覆盖原有数据
            JSONObject valueNode = new JSONObject();
            valueNode.put("value", value);
            systemNode.put(id, valueNode);

            // 自动管理流关闭,写入格式化后的JSON
            try (FileWriter writer = new FileWriter(targetFile)) {
                writer.write(root.toString(2));
            }
        }
    }
}
注意点
  • 当list中存在多条指向同一个文件路径的记录时,循环会依次读取上一次写入的内容做追加,最终就会得到预期的单个system节点下挂载多个id条目的结构
  • toString(2)方法会生成带2空格缩进的格式化JSON,和你给出的预期文件排版一致
  • 如果需要更高的写入可靠性,可以在写入完成后增加文件校验逻辑,避免写入中途磁盘满、进程被杀导致文件损坏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:36:07