【问题标题】:Adding JSON objects to existing JSON File将 JSON 对象添加到现有 JSON 文件
【发布时间】:2017-06-07 15:25:37
【问题描述】:

所以我最近的任务是创建一个实用程序,该实用程序允许通过 gson 库轻松地将 JSON 添加到 .json 文件中。我已经在 Kotlin 中编写了代码:

fun addObject(filePath: String, name: String, values: Array<Array<String>>) {
try {

    var writer: JsonWriter = JsonWriter(FileWriter(File(filePath)))
    writer.beginObject()
    writer.name(name)
    writer.beginObject()
    for(item in values){
        writer.name(item[0]).value(item[1])
    }
    writer.endObject()
    writer.endObject()

    writer.close()

    println("[JSONUtil] Wrote object successfully!")

} catch (e: IOException) {
    e.printStackTrace()
}
}

我使用二维数组来允许用户在所述对象中添加具有任意数量值的不同对象。例如,您可以这样运行它:

addObject("C:\\Users\\Test\\Desktop\\JsonUtility\\output.json", "GENERAL", 
arrayOf(arrayOf("POS_X","2"), arrayOf("POS_Y","4")))

这将创建以下 JSON:

{"GENERAL":{"POS_X":"2","POS_Y":"4"}}

这就是它的意图和工作方式,我的问题是,再次运行该函数时,它会完全覆盖文件中以前的 JSON,这显然很糟糕。

我的问题是:

  • 如何在整个文件中或在特定点添加新的 JSON 对象,例如本示例中的“addObject("GENERAL", ...)"?

  • 我怎样才能做得更好?

我对 Kotlin 还很陌生,并且主要使用 Java 进行编码,所以 Java 解决方案很好,因为我确信我能够转换它。

提前致谢!

编辑:新代码,不知道如何实现它:

fun UpdateJson(path: String, name: String, value: String){
    var gson = Gson()
    var reader: FileReader = FileReader(File(path))

    val type = object : TypeToken<Map<String, String>>() {}.type
    println("Type: " + type.toString())
    println("Existing Json: ${gson.fromJson<Map<String,String>>
    (JsonReader(reader), type)}")
    var existingJson: Map<String, String> = 
    gson.fromJson<Map<String,String>>(JsonReader(reader), type)
    existingJson.put(name, value)
    FileWriter(File(path)).use({ writer -> 
    writer.write(gson.toJson(existingJson)) })
}

【问题讨论】:

  • catch (e: IOException = java.io.IOException) 错误,应该是catch (e: IOException)。或者你可以完全删除 catch。
  • 谢谢,会做出改变的。还有更多提示吗?
  • 你需要先读取json,然后添加新元素,最后保存。
  • @KrisRoofe 添加新元素是我遇到的困难。我怎样才能让用户可以指定一个对象来添加新元素?

标签: java json kotlin


【解决方案1】:

最简单的方法是,正如@KrisRoofe 建议的那样,读取 json,然后添加一个元素。我会通过converting the existing json in the file to a Map 做到这一点。由于您实际上并不关心现有的 json,因此您要做的就是向该 Map 添加一个新条目。一旦你这样做了,只需将新的地图写入文件。你可以这样做:

public class UpdateJson {
    public static void main(String[] args) throws IOException {
        addObject("example.json", "GENERAL", arrayOf(arrayOf("POS_X","2"), arrayOf("POS_Y","4")));
    }

    private static void addObject(String fileName, String newObjName, String newObjValue) throws IOException {
        Gson gson = new Gson();
        Type type = new TypeToken<Map<String, String>>(){}.getType();
        Map<String, String> existingJson = gson.fromJson(new JsonReader(new FileReader(new File(fileName))), type);
        existingJson.put(newObjName, newObjValue);
        try (FileWriter writer = new FileWriter(new File(fileName))) {
            writer.write(gson.toJson(existingJson));
        }
    }

    private static String arrayOf(String s1, String s2) {
        return "[" + s1 + ", " + s2 + "]";
    }
}

编辑: 上述解决方案是Java解决方案。 Kotlin 中的 Type 似乎存在问题。

  1. 这个Stack Overflow question 有一个使用object: 的解决方法
  2. 另外,请注意,要在 Kotlin 中使用反射,您需要一个单独的 jar,根据 Kotlin documentation'

编辑 2:提供 Kotlin 答案:

fun main(args: Array<String>) {
    addObject("example.json", "GENERAL", arrayOf(arrayOf("POS_X", "2"), arrayOf("POS_Y", "4")))
}


fun addObject(path: String, name: String, value: String) {
    val gson = Gson()
    val reader: FileReader = FileReader(File(path))
    val type = object : TypeToken<Map<String, String>>() {}.type
    System.out.println("Type: " + type.toString())
    val existingJson = gson.fromJson<Map<String, String>>(JsonReader(reader), type)
    System.out.println("Existing Json: ${existingJson}")
    val newJsonMap = existingJson.plus(Pair(name, value))
    FileWriter(File(path)).use(
        { writer -> writer.write(gson.toJson(newJsonMap)) }
    )
}

fun arrayOf(s1: String, s2: String): String {
    return "[$s1, $s2]"
}

【讨论】:

  • 嗯,Type 类有一些困难,似乎与 Kotlin 不兼容,因为 Java 到 Kotlin 的转换删除了“Type”类型并将其替换为“object”,然后导致推理错误。 Type 有什么替代品吗?
  • 只需将其改回 Type,它在 Kotlin 中运行良好。 @CoalCoding 您是在要求人们编写您的代码,而不是一个特定的问题。
  • 如果我将它改回类型,它会在“.type”处显示“未解析的引用“类型”,它会将其转换为最后。“.getType()”是相同的。
  • 非常感谢。这解决了问题。
  • 这解决了我的问题。错误是由于使用了不正确的格式。现在一切正常,我意识到不阅读 gson 文档我很愚蠢。感谢所有的帮助。
猜你喜欢
  • 2021-11-12
  • 2016-01-09
  • 2018-02-08
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-29
  • 1970-01-01
相关资源
最近更新 更多