esp32实现简单的kv数据库

我来帮你优化代码,使用 SPIFFS (SPI Flash File System) 来实现数据持久化存储。

#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <FS.h>
#include <ArduinoJson.h>

// WiFi 设置
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";

// 创建 WebServer 实例,端口 80
ESP8266WebServer server(80);

// 数据文件路径
const char* dataFile = "/kvstore.json";

// 用于临时存储数据的 JSON 对象
DynamicJsonDocument kvStore(4096); // 4KB 存储空间

void setup() {
  Serial.begin(115200);
  
  // 初始化 SPIFFS
  if (!SPIFFS.begin()) {
    Serial.println("SPIFFS 初始化失败");
    return;
  }
  
  // 从文件加载数据
  loadData();
  
  // 连接 WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi 已连接");
  Serial.println("IP 地址: ");
  Serial.println(WiFi.localIP());

  // 设置 API 路由
  server.on("/kv", HTTP_GET, handleGet);
  server.on("/kv", HTTP_POST, handlePost);
  server.on("/kv", HTTP_PUT, handlePut);
  server.on("/kv", HTTP_DELETE, handleDelete);

  server.begin();
}

void loop() {
  server.handleClient();
}

// 从文件加载数据
void loadData() {
  if (SPIFFS.exists(dataFile)) {
    File file = SPIFFS.open(dataFile, "r");
    if (!file) {
      Serial.println("打开文件失败");
      return;
    }
    
    DeserializationError error = deserializeJson(kvStore, file);
    if (error) {
      Serial.println("解析 JSON 失败");
    }
    
    file.close();
  }
}

// 保存数据到文件
void saveData() {
  File file = SPIFFS.open(dataFile, "w");
  if (!file) {
    Serial.println("创建文件失败");
    return;
  }
  
  serializeJson(kvStore, file);
  file.close();
}

// 获取值
void handleGet() {
  String key = server.arg("key");
  if (key == "") {
    server.send(400, "text/plain", "需要提供 key 参数");
    return;
  }
  
  if (kvStore.containsKey(key)) {
    String value = kvStore[key].as<String>();
    server.send(200, "text/plain", value);
  } else {
    server.send(404, "text/plain", "未找到该 key");
  }
}

// 创建新的 key-value
void handlePost() {
  String key = server.arg("key");
  String value = server.arg("value");
  
  if (key == "" || value == "") {
    server.send(400, "text/plain", "需要提供 key 和 value 参数");
    return;
  }
  
  if (kvStore.containsKey(key)) {
    server.send(409, "text/plain", "key 已存在");
    return;
  }
  
  kvStore[key] = value;
  saveData();
  
  server.send(201, "text/plain", "创建成功");
}

// 更新已存在的值
void handlePut() {
  String key = server.arg("key");
  String value = server.arg("value");
  
  if (key == "" || value == "") {
    server.send(400, "text/plain", "需要提供 key 和 value 参数");
    return;
  }
  
  if (kvStore.containsKey(key)) {
    kvStore[key] = value;
    saveData();
    server.send(200, "text/plain", "更新成功");
  } else {
    server.send(404, "text/plain", "未找到该 key");
  }
}

// 删除 key-value
void handleDelete() {
  String key = server.arg("key");
  
  if (key == "") {
    server.send(400, "text/plain", "需要提供 key 参数");
    return;
  }
  
  if (kvStore.containsKey(key)) {
    kvStore.remove(key);
    saveData();
    server.send(200, "text/plain", "删除成功");
  } else {
    server.send(404, "text/plain", "未找到该 key");
  }
}

主要改进:

  1. 添加了 SPIFFS 文件系统支持
  2. 使用 ArduinoJson 库来处理 JSON 数据
  3. 数据持久化存储在 flash 中的 JSON 文件
  4. 去掉了固定大小数组的限制

使用前准备:

  1. 需要安装 ArduinoJson 库(通过 Arduino IDE 的库管理器安装)
  2. 第一次使用需要格式化 SPIFFS(可以使用 Arduino IDE 的 “ESP8266 Sketch Data Upload” 工具)

新增功能:

  1. 设备重启后数据不会丢失
  2. 使用 JSON 格式存储数据,更灵活
  3. 存储容量更大(取决于 ESP8266 的 flash 大小)

使用注意:

  1. DynamicJsonDocument 的大小设置为 4KB,可以根据需要调整
  2. 频繁写入可能会影响 flash 寿命,建议适当控制写入频率
  3. 确保 ESP8266 有足够的闪存空间

API 使用方式与之前相同:

  1. 获取值 (GET)

    http://[设备IP]/kv?key=测试key
    
  2. 创建新值 (POST)

    http://[设备IP]/kv?key=测试key&value=测试value
    
  3. 更新值 (PUT)

    http://[设备IP]/kv?key=测试key&value=新value
    
  4. 删除值 (DELETE)

    http://[设备IP]/kv?key=测试key
    

如果需要进一步优化,可以考虑:

  1. 添加数据压缩
  2. 实现数据备份
  3. 添加访问认证
  4. 添加批量操作接口
  5. 实现数据定期自动保存

猜你喜欢

转载自blog.csdn.net/u011027104/article/details/143501057