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()方法取值
修复方案
调整核心处理逻辑:
- 读取目标文件的JSON内容后,先取出已经存在的
system节点对象,如果节点不存在再新建空的JSONObject,不要直接替换整个system节点 - 往取出的已有
system节点中,以当前遍历到的id变量为键,放入对应的value对象,实现追加效果 - 用try-with-resources语法自动管理文件写入流,保证异常场景下流也能被正常关闭
- 补充空数据、文件不存在的边界场景判断,避免运行时异常
修复后的可运行代码示例:
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
相关产品推荐
相关产品推荐

