在磁盘上的JSON文件中追加一个JSON数组,每秒使用c++

Append to a JSON array in a JSON file on disk, every second using C++

本文关键字:JSON 数组 一个 c++ 磁盘 文件 追加      更新时间:2023-10-16

这是我在这里的第一个帖子,所以请耐心等待。

我在网上到处寻找答案,但我一直没能解决我的问题,所以我决定在这里写一个帖子。

我正试图用c++和JZON写(追加)到文件上的JSON数组,以每秒1写的间隔。JSON文件最初是由"Prepare"函数编写的。然后每秒调用另一个函数,向JSON文件添加一个数组,并每秒向数组添加一个新对象。

我尝试了很多事情,其中大多数都导致了各种各样的问题。我最近的尝试给了我最好的结果,这是我在下面包含的代码。然而,我采用的方法效率非常低,因为我每秒钟都要写一个整个数组。随着数组的增长,这会对CPU利用率产生巨大的影响,但对内存的影响并不像我最初预期的那么大。

我真正希望能够做的是附加到磁盘上JSON文件中包含的现有数组,逐行,而不是必须从JSON对象中清除整个数组并重写整个文件,每秒钟。

我希望这个网站上的一些天才能给我指出正确的方向。

提前谢谢你。

下面是我的代码:
//Create some object somewhere at the top of the cpp file
Jzon::Object jsonFlight;
Jzon::Array jsonFlightPath;
Jzon::Object jsonCoordinates;
int PrepareFlight(const char* jsonfilename) {
  //...SOME PREPARE FUNCTION STUFF GOES HERE...
  //Add the Flight Information to the jsonFlight root JSON Object
  jsonFlight.Add("Flight Number", flightnum);
  jsonFlight.Add("Origin", originicao);
  jsonFlight.Add("Destination", desticao);
  jsonFlight.Add("Pilot in Command", pic);
  //Write the jsonFlight object to a .json file on disk. Filename is passed in as a param    of the function.
  Jzon::FileWriter::WriteFile(jsonfilename, jsonFlight, Jzon::NoFormat);
  return 0;
}
int UpdateJSON_FlightPath(ACFT_PARAM* pS, const char* jsonfilename) {
  //Add the current returned coordinates to the jsonCoordinates jzon object
  jsonCoordinates.Add("altitude", pS-> altitude);
  jsonCoordinates.Add("latitude", pS-> latitude);
  jsonCoordinates.Add("longitude", pS-> longitude);
  //Add the Coordinates to the FlightPath then clear the coordinates.
  jsonFlightPath.Add(jsonCoordinates);
  jsonCoordinates.Clear();
  //Now add the entire flightpath array to the jsonFlight object.
  jsonFlight.Add("Flightpath", jsonFlightPath);
  //write the jsonFlight object to a JSON file on disk.
  Jzon::FileWriter::WriteFile(jsonfilename, jsonFlight, Jzon::NoFormat);
  //Remove the entire jsonFlighPath array from the jsonFlight object to avoid duplicaiton next time the function executes.
  jsonFlight.Remove("Flightpath");
  return 0;
}

当然你可以自己做"平面文件"存储。但这是需要数据库的症状。一些非常轻的东西,比如SQLite,或者中等权重的&如MySQL, FireBird,或PostgreSQL等。

至于你的问题:

1)不使用结束[括号,保持文件打开&追加——但如果你没有正确关闭文件,它将被损坏&需要修复才能可读。

2)你当前的选项——每次写一个完整的文件——也不安全,因为你"打开覆盖"的那一刻,你失去了以前存储在文件中的所有数据。这里的解决方法是在开始写入之前将重命名为旧文件作为备份。

您还应该使用第一个选项对文件进行备份。(每天说一次)。否则,数据丢失很可能最终发生——按Ctrl-C,电源丢失,程序错误或系统崩溃。

当然,如果你使用SQLlite, MySQL, Firebird或PostgreSQL中的任何一个,所有的数据完整性问题都会为你处理。