SPIFFS的使用

SPIFFS

我个人很喜欢ESP8266这个板,主要是由于它提供了一系列价格低廉、高可用的IoT开发及接入方案。你是否知道在ESP8266的系统闪存可以用来存储代码甚至是文件吗?

这个文件系统可以让我们存储一些变更频率不频繁的文件例如网页、配置或者是某些固化的数据等。芯片内置这样的小型文件系统后ESP8266就相当于是一块Arduino+WIFI+SD扩展板的功能了,但价格上却只需要比Arduino低上很多。正因为了它我们就能在里面植入一些其它的固件用于支持像Lua或者Micropython这样的脚本类语言引擎以简化嵌入式设备的编程。

它就是SPIFFs - SPI Flash Filing System!

环境配置

那怎么来使用SPIFFs呢?首先你需要在Arduino中加入对ESP8266这个板子的支持,在我以前的文章Arduino Core For ESP8266中对此已经有所介绍。其次,你需要下载一个Arduino IDE的插件Arduino-ESP8266FS-Plugin,解压缩至<home>/Arduino/tools/然后重启Arduino后就会看到ESP8266 Sketch Data Upload 的菜单。

ESP8266由于有很多种不同的板子,所以在使用SPIFFS之前应该先确认你所用的板子的SPIFFS的大小。

目录
Arduino IDE 插件

Flash的结构:

以下是ESP8266的Flash基本结构:

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
      Sketch    OTA更新   文件系统   EEPROM  WiFi config (SDK)

文件系统的大小依赖于Flash芯片的大小,下表为现时收集到的常见芯片的FLash大小:

主板 Flash(bytes) 文件系统(bytes)
Generic module 512k 64k
Generic module 1M 64k, 128k, 256k, 512k
Generic module 2M 1M
Generic module 4M 3M
Adafruit HUZZAH 4M 1M, 3M
NodeMCU 0.9 4M 1M, 3M
NodeMCU 1.0 4M 1M, 3M
Olimex MOD-WIFI-ESP8266(-DEV) 2M 1M
SparkFun Thing 512k 64k
SweetPea ESP-210 4M 1M, 3M
WeMos D1 & D1 mini 4M 1M, 3M

注:在使用SPIFFS功能之前需要在文件内引用头文件:
#include "FS.h"

使用SPIFFS

ESP8266FS插件其实只是在当前项目目录下创建了一个data目录,我们只要将需要上传到芯片文件系统的内容放置在这个 data目录中就可以了,然后点击ESP8266 Skech Data Upload Arduino IDE就会将这个目录的文件写入到SPIFFS中了。要注意的是文件的大小不能超过板子SPIFFS的大小,否则会上传失败。

我们就尝试将一个index.html网页文件放到data目录,然后将其上传到ESP8266中,接下来用以下的代码将SPIFFS中的index.html读出来:


#include"FS.h"

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

  bool ok = SPIFFS.begin();
  if (ok) {
    Serial.println("ok");
    //检查文件是否存在
    bool exist = SPIFFS.exists("/index.html");

    if (exist) {
      Serial.println("The file exists!"); 

      File f = SPIFFS.open("/index.html", "r");
      if (!f) {
        // 在打开过程中出现问题f就会为空
        Serial.println("Some thing went wrong trying to open the file...");
      }
      else {
        int s = f.size();
        Serial.printf("Size=%d\r\n", s);

        //读取index.html的文本内容
        String data = f.readString();
        Serial.println(data);

        //关闭文件
        f.close();
      }
    }
    else {
      Serial.println("No such file found.");
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

FS的参考

SPIFFS对象

begin

SPIFFS.begin()

该方法用于挂载SPIFFS文件系统,必须在使用SPIFFS之前就调用,一般都会在setup()过程调用。该方法如果调用成功将会返回true,否则返回false

format

SPIFFS.format()

格式化文件系统。返回true表示格式化成功。

open

SPIFFS.open(path, mode)

打开指定位置上的一个文件并返回File对象。

  • path - 文件的路径(如:/test.text)
  • mode - 文件的读写模式,可以为 "r", "w", "a", "r+", "w+", "a+"中的任意一个,这个与C言语中访问文件系统的方式是一样的。

该方法返用成功后会返回一个File对象,否则就会返回空。

File f = SPIFFS.open("/f.txt", "w");
if (!f) {
    Serial.println("file open failed");
}

exists

SPIFFS.exists(path)

检测指定文件或目录是否存在。

openDir

SPIFFS.openDir(path)

打开指定目录并返回一个目录对象实例。

remove

SPIFFS.remove(path)

删除指定绝对路径上的文件或目录。

rename

SPIFFS.rename(pathFrom, pathTo)

重命名。

info

FSInfo fs_info;
SPIFFS.info(fs_info);

获取一个文件系统信息结构。

文件系统信息结构

struct FSInfo {
    size_t totalBytes;   // 可用量
    size_t usedBytes;  // 已用
    size_t blockSize;   // 块大小
    size_t pageSize;  // 页大小
    size_t maxOpenFiles; // 最大打开文件数
    size_t maxPathLength; // 最大文件路径长度
};

目录 (Dir)

目录对象常用于枚举,它会提供三个方法:next(),fileName(), 和 openFile(mode)

以下例子用于枚举指定目录下的子目录、文件名和文件大小:

Dir dir = SPIFFS.openDir("/data");
while (dir.next()) {
    Serial.print(dir.fileName());
    File f = dir.openFile("r");
    Serial.println(f.size());
}

dir.next()返回真时就表示目录枚举完成。它的调用必须早于fileNameopenFile函数。

文件对象

SPIFFS.opendir.openFile 函数都可以返回一个File文件对象实例。这个对象用于处理所有的文件流,例如:readBytes, findUntil, parseInt, println

seek

file.seek(offset, mode)

移动文件指针。

position

file.position()

返回当前文件指针的位置 。

size

file.size()

返回文件的大小。

name

String name = file.name();

返回文件名。

close

file.close()

关闭并释放文件对象。

在实际的运用场景中,合理地使用SPIFFS会给我们省下很多的时间甚至是生产成本,希望这篇短文能给你在使用ESP8266的过程中给予一些帮助。

ESP8266 Core 参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容