Intereting Posts
Regex – слова соответствия, которые не являются строками Преобразование устаревших методов из Java в Kotlin Запуск Котлинского кодекса на платформе SBT / Play? RxJava Live Reactive Queue (с выключенным переключателем) Как вызвать конструктор родового типа в конструкторе класса Почему тексты не меняются в действии? Сбор Kotlin + Maven: нет основного атрибута манифеста Библиотека Kotlin 'rxkotlin-0.21.0.jar' имеет неподдерживаемый формат. Обновите библиотеку или плагин Котировка класса данных Котлина с измененным значением var Есть ли способ идентифицировать класс данных Kotlin из обычного класса Kotlin? Создание публичного экземпляра частного внутреннего класса в Котлине Как получить родительский класс внутри анонимного класса в kotlin Не удается выполнить единичный тест в Kotlin (ExecutionException, Aapt2Exception) Невозможно предоставить квалифицированную строку с помощью Dagger2 Как добавить серию в диаграмму JavaFX в котлин

Добавление объектов JSON в существующий файл JSON

Поэтому мне недавно было поручено создать утилиту, которая позволит легко добавлять JSON в файл .json через библиотеку gson. Я закодировал это в Котлине:

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 во весь файл или в определенные моменты, например «addObject (« GENERAL », …)» для этого примера?

  • Как я могу сделать это лучше?

Я довольно новичок в Kotlin и в основном кодируюсь на Java, поэтому Java-решения прекрасны, так как я уверен, что смогу его преобразовать.

Заранее спасибо!

EDIT: Новый код, не знаю, как его реализовать:

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

Solutions Collecting From Web of "Добавление объектов JSON в существующий файл JSON"

Самый простой способ – это, как предложил @KrisRoofe, прочитать json, а затем добавить элемент. Я бы сделал это, преобразовывая существующий json в файл в Map . Поскольку вы действительно не заботитесь о существующем json, все, что вы хотите сделать, это добавить новую запись на эту карту. Как только вы это сделаете, просто напишите новую карту в файл. Вы можете сделать это так:

 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 + "]"; } } 

EDIT: вышеупомянутое решение является решением Java. Кажется, что проблема связана с Type в Котлине.

  1. Этот вопрос переполнения стека имеет обходное решение, используя object:
  2. Кроме того, обратите внимание, что для использования рефлексии с Котлином вам нужна отдельная банка, согласно документации Котлина "

EDIT 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]" }