将JSON对象添加到现有JSON文件

时间:2017-06-07 15:25:38

标签: java json kotlin

所以我最近的任务是创建一个实用程序,它允许通过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()
}
}

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

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对象,例如&#34; addObject(&#34; GENERAL&#34;,...)&#34;这个例子?

  • 我怎样才能做得更好?

我对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)) })
}

1 个答案:

答案 0 :(得分:0)

最简单的方法是,正如@KrisRoofe建议的那样,读取json,然后添加一个元素。我会通过converting the existing json in the file to a Map来做到这一点。由于您实际上并不关心现有的json,所以您要做的就是向该Map添加一个新条目。完成后,只需将新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. 进行解决
  3. 另外,请注意,要使用Kotlin反射,根据Kotlin documentation'
  4. ,您需要一个单独的jar

    编辑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]"
    }