добавить в json данные

notfound
Offline
Зарегистрирован: 09.04.2022

День добрый. Помогите пожалуйста, второй день ковыряюсь не могу въехать в чем косяк.

Задача такая. на SPIFFS имеется файл test.json с уже какими то записями формата

"data": {
    "name": [
      "PRIVET"
 
    ],
    "surname": [
      "MEDVED"
    ]
  }
}
И нужно при допустим нажатии кнопки добавлять в этот файл данные из переменных.
вот код моей функции
void writejson(String valueName, String valueSurname){
DynamicJsonDocument doc1(1024);
File file = SPIFFS.open("/test.json", "r");

DeserializationError error = deserializeJson(doc1, file);
if (error) {
Serial.print(F("deserializeJson() Error: "));
Serial.println(error.f_str());
return;
}
file.close();
const char* name;
recname=doc1["name"].size();
const char* surname
recsur=doc1["surname"].size();

DynamicJsonDocument doc2(1024);

JsonObject root = doc2.to<JsonObject>();
JsonObject data = root.createNestedObject("data");
for(int i=0; i<recname; i++ ){
name = doc1["name"][i];
data["name"].add(name);

}
data["name"].add(valueName);
for(int n=0; n<recpass; n++ ){
surname = doc1["surname"][n];
data["surname"].add(surname);
}
data["surname"].add(valueSurname);

file = SPIFFS.open("/test.json", "w");

if (serializeJsonPretty(root, file)){
Serial.println("Ништяк, файлик записан");
}else {
Serial.print ("Не могу записать файл, прости хозяин!!");
}
file.close();
}
 
 
Так вот если только залить новый файл json  с какими то данными и первый раз выполнить эту функцию, то все работает как надо, в конец каждого ключа массива дописывается данные из переменных функции,
"data": {
    "name": [
      "PRIVET",
     "Pjfdfg"
 
    ],
    "surname": [
      "MEDVED",
     "ghjkl"
    ]
  }
}
Но если еще раз выполнить эту функцию, то уже файл просто перезаписывается только с данными из переменных,
"data": {
    "name": [
     "Pjfdfg"
 
    ],
    "surname": [
     "ghjkl"
    ]
  }
}
и если еще раз выполнить функцию то опять перезаписывает не добавляя данные а перезаписывая новые.
"data": {
    "name": [
     "Pjfdfg"
 
    ],
    "surname": [
     "ghjkl"
    ]
  }
}
Если открыть файл с ключом "a", то данные дописываются в конец
"data": {
    "name": [
     "Pjfdfg"
 
    ],
    "surname": [
     "ghjkl"
    ]
  }
}
"data": {
    "name": [
     "Pjfdfg"
 
    ],
    "surname": [
     "ghjkl"
    ]
  }
}
вот такого вида получается. Но мне так не надо.
Очень прошу помощи. И прошу сильно не пинать если кому то покажется этот код убогим.
Поверьте я много чего перепробовал.

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018
rkit
Offline
Зарегистрирован: 23.11.2016

Нафига ты второй объект в памяти создаешь? Редактируй имеющийся.

notfound
Offline
Зарегистрирован: 09.04.2022

Подскажи плиз если не сложно, как с одним объектом это провернуть. Я уже реально не знаю как решить. Но капец как нужно.

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

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

В строке под номером ХЗ не закрывай файл, а работай с ним дальше (вместо второго объекта). Предварительно открыв его для записи, конечно же.

notfound
Offline
Зарегистрирован: 09.04.2022

понял, спасибо большое

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Чо мое сообщение #1 игнорируешь???

Хотя если понял - то пофиг. Но ознакомиться обязательно нужно!!!

notfound
Offline
Зарегистрирован: 09.04.2022

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

 

notfound
Offline
Зарегистрирован: 09.04.2022

Хрен там был, не дает первое сообщение изменить, нету кнопки даже.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Вставь в новом сообщении.

notfound
Offline
Зарегистрирован: 09.04.2022
void writejson(String valueName, String valueSurname){
DynamicJsonDocument doc1(1024);
File file = SPIFFS.open("/test.json", "r");
DeserializationError error = deserializeJson(doc1, file);
if (error) {
Serial.print(F("deserializeJson() Error: "));
Serial.println(error.f_str());
return;
}
file.close();
const char* name;
recname=doc1["name"].size();
const char* surname;
recsur=doc1["surname"].size();
DynamicJsonDocument doc2(1024);
JsonObject root = doc2.to<JsonObject>();
JsonObject data = root.createNestedObject("data");
for(int i=0; i<recname; i++ ){
name = doc1["name"][i];
data["name"].add(name);
}
data["name"].add(valueName);
for(int n=0; n<recpass; n++ ){
surname = doc1["surname"][n];
data["surname"].add(surname);
}
data["surname"].add(valueSurname);
file = SPIFFS.open("/test.json", "w");
if (serializeJsonPretty(root, file)){
Serial.println("Ништяк, файлик записан");
}else {
Serial.print ("Не могу записать файл, прости хозяин!!");
}
file.close();
}
 

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Ну я сразу говорю - с json дел не имел, но по логике должно быть как-то так:

void writejson(String valueName, String valueSurname) {
  DynamicJsonDocument doc1(1024);
  File file = SPIFFS.open("/test.json", "r");
  DeserializationError error = deserializeJson(doc1, file);
  if (error) {
    Serial.print(F("deserializeJson() Error: "));
    Serial.println(error.f_str());
    return;
  }
  file.close();
  doc1["name"].add(valueName);
  doc1["surname"].add(valueSurname);
  file = SPIFFS.open("/test.json", "w");
  if (serializeJsonPretty(doc1, file)) {
    Serial.println("Ништяк, файлик записан");
  } else {
    Serial.print ("Не могу записать файл, прости хозяин!!");
  }
  file.close();
}

У самого то что получилось?

notfound
Offline
Зарегистрирован: 09.04.2022

Капец дружище ты не представляешь как я тебе БЛАГОДАРЕН. 

У меня пока не до конца получилось подправить. Но на твоем примере все ништяк работает. Я как обычно перемудрил слегка, если можно так сказать. Еще раз ОГРОМНОЕ тебе СПАСИБО!

notfound
Offline
Зарегистрирован: 09.04.2022

Блин смотрю ща на код, и просто поражаюсь на сколько все было проще чем я замудрил. Я почему то был уверен что надо двумя объектами и потом их объединять в цикле. а оказалось все на много проще))))). Спасибо, спасибо спасибо!!

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Я бы еще обрабатывал ошибки фс, например:

enum ERROR_LIB : uint8_t {    // Добавим перечисление для обработки возможных ошибок
  NO_ERROR = 1,               // - Все отлично, ошибок нет 
  ERROR_READ_WRITE_FILE       // - Ошибка доступа к файлу (ошибка чтения или записи, можно разделить: ERROR_READ_FILE / ERROR_WRITE_FILE , если необходимо)
};                            // Ну и еще по необходимости можно добавить...

uint8_t writejson(String valueName, String valueSurname) {
  DynamicJsonDocument doc1(1024);
  File file = SPIFFS.open("/test.json", "r");
  DeserializationError error = deserializeJson(doc1, file);
  if (error) {
    return ERROR_READ_WRITE_FILE;
  }
  file.close();
  doc1["name"].add(valueName);
  doc1["surname"].add(valueSurname);
  file = SPIFFS.open("/test.json", "w");
  if (!serializeJsonPretty(doc1, file)) {
    return ERROR_READ_WRITE_FILE;
  }
  file.close();
  return NO_ERROR;
}

А в основной программе:

uint8_t writeState = writejson(valueName, valueSurname);

if (writeState == ERROR_READ_WRITE_FILE) {
  // Как-то сигнализируем об ошибке в работе с файловой системой и останавливаем работу (если это необходимо)
}
notfound
Offline
Зарегистрирован: 09.04.2022

Спасибо большое за идею. Я ща думаю как из input text(html) передать данные в переменные из этой функции. А потом уже буду доводить до ума все остальное. Там еще один нюанс появился, что иногда(редко) при записи в файл json попадает мусор всякий, но это наверно из-за того что функция срабатывает при нажатии кнопки, и когда мусор попадает в файл, то deserealization уже не выполняется, так как файл не соответствует содержанием формату json. Но это мелочь

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Прежде чем передать значения в функцию нужно их проверять на мусор и т.п.

notfound
Offline
Зарегистрирован: 09.04.2022

Ну я так и поступлю. Спасибо тебе еще раз огромнейшее