首页 > 解决方案 > Arduino ESP 编辑大 JSON 文件 - 磨损均衡

问题描述

我有一个大约 1000 个对象的“大”JSON 文件。
使用https://arduinojson.org/进行序列化/反序列化。

void ConfigFile_Save_Variable(String VarName, String VarValue) {
  Serial.print("ConfigFile_Save_Variable: ");
  Serial.print(VarName); Serial.print("="); Serial.print(VarValue);

  File configFile = SPIFFS.open("/config.json", "r");
  if (!configFile) {
    Serial.println("- failed to open config file for writing");
    return;
  }

  DynamicJsonDocument doc(2048);
  deserializeJson(doc, configFile);
  serializeJson(doc, Serial);
  configFile.close();
  //
  doc[VarName] = VarValue;
  //
  configFile = SPIFFS.open("/config.json", "w");
  serializeJson(doc, configFile);
  serializeJson(doc, Serial);
  configFile.close();
  Serial.println("");
  Serial.println(" - config.json saved - OK.");

如果我只想编辑 1 个对象并保存 JSON 文件,则重新写入整个文件。
这不利于磨损均衡,因为它会再次写入所有数据,但只有 1 个对象已更改。

所以我正在寻找一种只写更改而不是整个文件的方法。尝试到处寻找没有运气。

标签: c++arduinoesp8266esp32arduino-esp8266

解决方案


TLDR:手动磨损均衡非常困难,无论如何均衡可能是自动的。我会将经常更改的配置选项分离到一个不同的文件中,这样你每次写的更少,并且只有在你绝对需要时才写入磁盘(即:程序结束)

如果 json 文件的长度发生变化,即:将“true”更改为“false”,则必须重写整个文件,因为必须分配给文件的 [disc] 空间现在已经更改。如果您为每个配置值保留一定数量的字符,或者仅使用 x 位数字作为配置值,您可能可以直接重写磁盘上的二进制数据,而无需与文件交互。但这需要一些极低级的编程,以及确切的内存地址知识。此外,由于您使用闪存进行存储,您仍然需要为每次更改读取、更新和写入一个完整的内存块。随着时间的推移,特别是如果您只定期更新一个值,从长远来看,与完全重写相比,这可能对磁盘造成更大的损害。

桌面 SSD 将自动平衡整个磁盘的磨损。如果 esp 也这样做,那么您不必担心自己会磨损,而是在重写文件时将文件大小保持在最低限度。

鉴于上述情况,一种可能的解决方案是将经常重写的配置选项分离到一个单独的文件中,并将很少重写的配置选项保留在主文件中。您还可以将所有配置数据保存在内存中,并且仅在程序结束时重写文件,但这仅适用于您不经常启动/停止程序的情况。将分离发挥到极致,理论上您可以为每个配置选项使用单独的文件,这将允许您一次只重写一个值。


推荐阅读