Проблемы с записью данных в файл JSON без перезаписи предыдущих данных при нескольких запусках (с использованием Джексона)

Я пытаюсь получить входную информацию пользователя, сохранить ее в файле JSON, а затем иметь возможность вводить дополнительную информацию при другом запуске, не перезаписывая весь файл. Идея состоит в том, что он будет работать как база данных учетных записей.

Хотя мой код включает в себя гораздо больше, чем этот фрагмент, по сути это то, что мне нужно. Кроме того, я использую IntelliJ IDEA в качестве своей IDE.

public static void accountSetup() throws IOException {
    // Variables
    File accounts = new File("accounts.json");
    ObjectMapper mapper = new ObjectMapper();
    ArrayNode arNode = mapper.createArrayNode();
    ObjectNode obNode = mapper.createObjectNode();
    Scanner scan = new Scanner(System.in);
    
    // Get user info
    System.out.println("What is the account holder's name?");
    obNode.put("name",scan.nextLine());
    System.out.println("Please enter a 7-digit passcode");
    obNode.put("passcode",scan.nextInt());

    // Write to JSON file
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    arNode.add(obNode);
    mapper.writeValue(accounts,arNode);
}

Вот что я ожидаю от этого фрагмента (^), предполагая, что пользователь ввел «Сэм» и «1234567», а затем перезапустил программу и ввел «Макс» и «7654321»:

[
  {
    "name" : "Sam",
    "passcode" : 1234567
  },
  {
    "name" : "Max",
    "passcode" : 7654321
  }
]

Однако когда я пытаюсь запустить программу еще раз и ввести другую информацию, она полностью перезаписывает файл, оставляя мне следующее:

[
  {
    "name" : "Max",
    "passcode" : 7654321
  }
]

Я понимаю, что это как-то связано с тем, как ObjectMapper записывает в файл, и я немало покопался, но безрезультатно.

Я хотел бы продолжать использовать Jackson, поскольку он кажется мощным и надежным инструментом, когда дело доходит до JSON, и я начал проект, для которого он был предназначен, как средство изучения различных аспектов Java. Другими словами, я бы хотел оставить переключение библиотек на крайний случай.

Пожалуйста, имейте в виду, что я в лучшем случае едва начинающий программист, и некоторые вещи, которые могут показаться глупыми или очевидными, не для меня.

TL;DR По сути, я пытаюсь добавить ObjectNode в массив JSON между средами выполнения... и не могу этого понять. Будем очень благодарны любой помощи. Спасибо за ваше время.

Вы проверили, правильно ли вы прочитали файл, прежде чем пытаться добавить новую информацию?

SedJ601 16.05.2024 01:58

Я проверил ваш код и обнаружил, что вы неправильно читаете файл.

SedJ601 16.05.2024 02:21

@ SedJ601 Не могли бы вы пояснить, что это значит? Я предполагаю, что это как-то связано с файлом account = new File("accounts.json");

SourMnMs 16.05.2024 02:31
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я впервые использую Jackson, так что, возможно, есть способ получше. Я также вижу, что вы используете устаревшие методы. Это нехорошо.

Попробуйте делать все по порядку.

  1. Считайте файл в строку.
  2. Считайте строку в JsonNode.
  3. Запишите JsonNode в выходной JsonArray.
  4. Запишите данные из пользовательского ввода в тот же выходной JsonArray.
  5. Запишите выходной JsonArray в файл и перезапишите старый файл.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Scanner;

/**
 *
 * @author Sed
 */
public class JavaTestingTwo {

    public static void main(String[] args) 
    {
        try 
        {           
            File accounts = new File("accounts.json");
            String jsonString = Files.readString(accounts.toPath());
            
            
            
            ObjectMapper objectMapper = new ObjectMapper();  
            ArrayNode arNode = objectMapper.createArrayNode();
            
            JsonNode arrayNode = objectMapper.readTree(jsonString);
            if (arrayNode.isArray()) {
                // yes, loop the JsonNode and display one by one
                for (JsonNode node : arrayNode) {
                    ObjectNode obNode = objectMapper.createObjectNode();
                    System.out.println("Name: " + node.get("name").asText());
                    System.out.println("Passcode: " + node.get("passcode").asInt());
                    obNode.put("name", node.get("name").asText());
                    obNode.put("passcode", node.get("passcode").asInt());
                    arNode.add(obNode);
                }
            }
            
            // Get user info
            ObjectNode obNode = objectMapper.createObjectNode();
            Scanner scan = new Scanner(System.in);
            System.out.println("What is the account holder's name?");
            obNode.put("name",scan.nextLine());
            System.out.println("Please enter a 7-digit passcode");
            obNode.put("passcode",scan.nextInt());
    
            
            objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
            arNode.add(obNode);
            objectMapper.writeValue(accounts,arNode);
            
        } 
        catch (IOException ex)
        {
            System.out.println(ex.toString());
        }
    }
}

Выход

[ 
    {
        "name" : "Sam",
        "passcode" : 1234567
    }, 
    {
        "name" : "Max",
        "passcode" : 7654321
    }, 
    {
         "name" : "john",
         "passcode" : 1234567
    }
]

Большое спасибо! Это было чрезвычайно полезно. И последний вопрос: какие методы, которые я использовал, устарели?

SourMnMs 16.05.2024 03:21

На самом деле, методы, которые вы использовали, хороши. Моя IDE отображается как устаревшая. Вы не использовали его.

SedJ601 16.05.2024 04:28

Другие вопросы по теме