ESP32でJSONファイルから値を取得する

esp32でJSONを使う
ライブラリをインストール
![json.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494758/bb2de11e-b295-549b-1603-f81cd73b9112.png)
テスト用のjsonファイル
```php:test.json
{
	"items": [
		{
			"y": 10,
			"x": 10,
			"type": "btn",
			"width": 50,
			"height": 120,
			"func": "functionA"
		},
		{
			"y": 110,
			"x": 50,
			"type": "btn",
			"width": 150,
			"height": 20,
			"func": "functionB"
		}
	]
}
```
littlefsで読み込む
```
void readFile(fs::FS &fs, const char * path,char *buf){
  File file = fs.open(path);
  if(!file || file.isDirectory()){
      Serial.println("- failed to open file for reading");
      return;
  }

  int i=0;
  while(file.available())
  {
    *(buf+i) = file.read();
    i++;
  }
  *(buf+i) = '\0';

  file.close();
}
```

deserializeJsonで読み込んだjsonデータをStaticJsonDocumentに入れて辞書配列のように取り出せる
```
  StaticJsonDocument<300> doc;
  DeserializationError error = deserializeJson(doc, json_buf);

  if (error) {
    // エラーの場合
    Serial.println("err");
  } else {
    // 正常な場合
    Serial.println("Noerr");
    int testb = doc["items"][1]["y"];
    Serial.println(testb);
  }
```

全体コード
```php:main.ino
#include <Arduino.h>
#include "FS.h"
#include <LittleFS.h>
#include<ArduinoJson.h>

#define FORMAT_LITTLEFS_IF_FAILED true

//ディレクトリの表示
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\r\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("- failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println(" - not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("\tSIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void readFile(fs::FS &fs, const char * path,char *buf){
  File file = fs.open(path);
  if(!file || file.isDirectory()){
      Serial.println("- failed to open file for reading");
      return;
  }

  int i=0;
  while(file.available())
  {
    *(buf+i) = file.read();
    i++;
  }
  *(buf+i) = '\0';

  file.close();
}

void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\r\n", path);
    if(fs.remove(path)){
        Serial.println("- file deleted");
    } else {
        Serial.println("- delete failed");
    }
}


void setup(){
  Serial.begin(115200);

  //LittleFS初期化
  if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
      Serial.println("LittleFS Mount Failed");
      return;
  }

  listDir(LittleFS, "/", 3);  //ディレクトリ表示

  char json_buf[300];
  readFile(LittleFS, "/test.json",json_buf); //jsonファイル読み込み
  Serial.println(json_buf);

  //json解析
  StaticJsonDocument<300> doc;
  DeserializationError error = deserializeJson(doc, json_buf);
  Serial.println(json_buf);

  if (error) {
    // エラーの場合
    Serial.println("err");
  } else {
    // 正常な場合は値を取得して表示
    Serial.println("Noerr");
    JsonObject testa = doc["items"];
    int testb = doc["items"][1]["y"];
    Serial.println(testb);
  }

  Serial.println(doc["items"].size());
}

void loop(){

}
```

2023/3/13追加
よくよくリファレンス見たらdeserializeJsonがstreamに対応してるから↑みたいに一つ一つコピーせずにファイル渡してやればいけるみたい
```
//Jsonファイルの読み込み
void MyUtilJson::readJson(fs::FS &fs,const char *path,JsonDocument &doc)
{  
  File file = fs.open(path);  //jsonファイルオープン

  //json解析
  DeserializationError error = deserializeJson(doc, file);  //ファイル(Stream)からデシリアライズ

  file.close();
}
```

```php:リファレンスより抜粋
// writable input => zero-copy
DeserializationError deserializeJson(JsonDocument& doc, char* input);
DeserializationError deserializeJson(JsonDocument& doc, char* input, size_t inputSize);

// read-only input => duplication
DeserializationError deserializeJson(JsonDocument& doc, const char* input);
DeserializationError deserializeJson(JsonDocument& doc, const char* input, size_t inputSize);
DeserializationError deserializeJson(JsonDocument& doc, const __FlashStringHelper* input);
DeserializationError deserializeJson(JsonDocument& doc, const __FlashStringHelper* input, size_t inputSize);
DeserializationError deserializeJson(JsonDocument& doc, const String& input);
DeserializationError deserializeJson(JsonDocument& doc, const std::string& input);
DeserializationError deserializeJson(JsonDocument& doc, Stream& input);
DeserializationError deserializeJson(JsonDocument& doc, std::istream& input);
DeserializationError deserializeJson(JsonDocument& doc, JsonVariantConst input);
DeserializationError deserializeJson(JsonDocument& doc, std::string_view input);

template<typename Reader> // custom reader class (see below)
DeserializationError deserializeJson(JsonDocument& doc, Reader& input);
```