1

这是我在这里的第一篇文章,所以请多多包涵。

我在互联网上到处寻找答案,但我无法解决我的问题,所以我决定在这里写一篇文章。

我正在尝试使用 C++ 和 JZON 以每秒 1 次写入的间隔写入(附加)到文件上的 JSON 数组。JSON 文件最初由“准备”函数编写。然后每秒调用另一个函数以向 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;
}
4

1 回答 1

0

当然,您可以自己进行“平面文件”存储。但这是需要数据库的症状。像 SQLite 这样非常轻量级的东西,或者像 MySQL、FireBird 或 PostgreSQL 这样的中等重量和开源的东西。

但至于你的问题:

1) 关闭 ] 括号关闭,并保持文件打开和附加 - 但如果您没有正确关闭文件,它将被损坏并需要修复才能读取。

2)您当前的选择——每次写入一个完整的文件——也不能避免数据丢失,因为当您“打开以覆盖”时,您会丢失以前存储在文件中的所有数据。这里的解决方法是在开始编写之前将旧文件重命名为备份。

您还应该使用第一个选项制作文件的备份副本。(每天说一次)。否则最终可能会发生数据丢失——按Ctrl-C、断电、程序错误或系统崩溃。

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

于 2013-08-02T05:10:02.357 回答