ESP8266 SPIFFS文本文件读取返回奇怪的字符

时间:2017-08-01 16:59:52

标签: c++ arduino esp8266 spiffs

我正在尝试在ESP8266的SPIFFS中存储一些十六进制调色板,但是当我尝试检索它们时,我会得到一些奇怪的字符。代码和日志输出如下:

代码(ino文件):

#include "FS.h"                   // https://github.com/esp8266/Arduino/
#include <JsonParser.h>           // https://github.com/henrikekblad/ArduinoJson
#include <JsonGenerator.h>        // https://github.com/henrikekblad/ArduinoJson

using namespace ArduinoJson;

void setup(void) {
  Serial.begin(9600);
  SPIFFS.format();
  SPIFFS.begin();
  writeTxtFile("/palettes/warm.json", "[\"ffffff\",\"ed1414\",\"f6f336\",\"ff7e15\"]");
  writeTxtFile("/palettes/pastel.json", "[\"ffffff\",\"ff7b7b\",\"8fff70\",\"7878ff\"]");
  readPalettes();
}

void loop(void) {
}

bool readPalettes(void) {
  bool succeeded = true;
  Dir dir = SPIFFS.openDir("/palettes");
  while (dir.next()) {
    File palette = dir.openFile("r");
    if (!readFile(palette, loadPaletteJson)) succeeded = false;
    palette.close();
    yield();
  }
  return succeeded;
}

bool loadPaletteJson(char* json, String fileName) {
  Serial.print(fileName);Serial.print(F(": "));Serial.println(json);
  Parser::JsonParser<5> parser; // one palette is 1+4*1=5 tokens
  Parser::JsonArray p = parser.parseArray(json);
  if (p.success()) {
    //Store the palettes in a vector using a specific structure
    return true;
  } else {
    Serial.println(F("JSON parsing failed"));
  }
  return false;
}

bool readFile(File file, std::function<bool (char* json, String fileName)> callback) {
  if (file) {
    String fileName = file.name();
    size_t fileSize = file.size();
    Serial.print(F("Reading "));Serial.print(fileSize);Serial.print(F(" bytes from "));Serial.println(fileName);
    if (fileSize <= 1024) {
      char buf[fileSize];
      file.readBytes(buf, fileSize);
      return callback(buf, getBaseName(fileName));
    } else {
      Serial.println(F("file size is too large"));
    }
  } else {
    Serial.println(F("file open failed"));
  }
  return false;
}

String getBaseName(String fileName) {
  return fileName.substring(fileName.lastIndexOf('/') + 1, fileName.lastIndexOf('.'));
}

bool writeTxtFile(String path, String content) {
  File file = SPIFFS.open(path, "w");
  if (file) {
    Serial.print(F("Writing content: "));Serial.print(content);Serial.print(F(" to: "));Serial.println(path);
    file.print(content);
    file.close();
    return true;
  } else {
    Serial.print(F("file open failed: "));Serial.println(path);
  }
  return false;
}

Arduino的IDE控制台输出:

Writing content: ["ffffff","ed1414","f6f336","ff7e15"] to: /palettes/warm.json
Writing content: ["ffffff","ff7b7b","8fff70","7878ff"] to: /palettes/pastel.json
Reading 37 bytes from /palettes/warm.json
warm: ["ffffff","ed1414","f6f336","ff7e15"]⸮?8⸮?tu @
JSON parsing failed
Reading 37 bytes from /palettes/pastel.json
pastel: ["ffffff","ff7b7b","8fff70","7878ff"]⸮?8⸮?tu @
JSON parsing failed

我不明白为什么这些字符(⸮?8⸮?tu @)被添加到有限大小的缓冲区中。我尝试用下面这样的唯一指针替换我的缓冲区(char buf[fileSize];):std::unique_ptr<char[]> buf(new char[fileSize]);(在函数readFile中)在接下来的2个语句中使用buf.get()但是确切的同样的结果。

我错过了什么吗?

编辑: 正如下面提到的@leetibbett,我在尝试读取字节时正在写一个字符串。这是readFile函数的修正:

bool readFile(File file, std::function<bool (char* json, String fileName)> callback) {
  if (file) {
    String fileName = file.name();
    size_t fileSize = file.size();
    Serial.print(F("Reading "));Serial.print(fileSize);Serial.print(F(" bytes from "));Serial.println(fileName);
    if (fileSize <= 1024) {
      String content = file.readStringUntil('\n');
      return callback((char*)content.c_str(), getBaseName(fileName));
    } else {
      Serial.println(F("file size is too large"));
    }
  } else {
    Serial.println(F("file open failed"));
  }
  return false;
}

0 个答案:

没有答案