Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Странное поведение .json (https://javascript.ru/forum/node-js-io-js/82060-strannoe-povedenie-json.html)

Andrew505 07.03.2021 01:36

Странное поведение .json
 
Доброй ночи. Написал код для "левелинга": человек отправляет сообщение - в .json-файл записываются следующие данные:
{
   "id_пользователя": {
       "xp": 25,
       "forNextLevel": 100,
       "level": 0
    }
}

Какое-то время три свойства обновляются адекватно, никаких проблем не возникает.
Но, это продолжается недолго. Вскоре, в .json файле либо стираются все данные и в консоли появляется ошибка
SyntaxError: Unexpected end of JSON input

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

Запись в .json-файл ограничивается следующим:
let json_data = JSON.parse(fs.readFileSync("./data.json", "utf8"));
    
    json_data[что-то][что-то][что-то] = "что-то";

    fs.writeFile("./data.json", JSON.stringify(json_data, null, 2), (err) => {
      if (err) console.log(err)
    });


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

akiraki22lvl 19.09.2025 13:39

Проблема почти наверняка связана с одновременной записью в файл. В Node.js fs.writeFile работает асинхронно, и если несколько сообщений приходят почти одновременно, происходит несколько попыток прочитать и записать файл одновременно. В результате: часть данных может не успеть сохраниться, файл обрывается и возникает Unexpected end of JSON input; или записывается неполная/повторяющаяся структура, поэтому появляются лишние фигурные скобки.
Как это исправить? Использовать синхронную запись:
fs.writeFileSync("./data.json", JSON.stringify(json_data, null, 2));

Синхронная запись блокирует выполнение до окончания записи, и данные не перемешиваются. Или реализовать очередь на запись: не писать в файл, пока предыдущая запись не завершилась. Можно хранить все изменения в памяти и периодически сбрасывать их в файл. Проверять, что JSON.parse обрабатывает только полностью прочитанный файл, и обрабатывать возможные ошибки через try/catch. В общем, корень проблемы не в синтаксисе JSON, а в том, что несколько операций записи идут одновременно и конфликтуют.


Часовой пояс GMT +3, время: 11:37.