ESP32. Get started with the SPIFFS.h library to read, write, modify files

spiffs esp32 arduino library
Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

SPIFFS (Serial Peripheral Interface Flash File System) is a lightweight file system suitable (among others) for microcontrollers with SPI flash memory such as the ESP32 and ESP8266. The Arduino SPIFFS.h library allows access to flash memory as if it were a normal file system like that of a computer (and much simpler of course). We can read, write and add data to a file and perform some simple operations (format, rename, retrieve information, etc.)

Warning, the flash memory is limited to 10,000 write cycles. Optimize your code to reduce write operations to extend the life of your ESP32 projects.

Introducing the SPIFFS (SPI Flash File System)

SPIFFS (for Serial Peripheral Interface Flash File System) is a file system developed by Peter Andersson (project page on GitHub) that can run on any NOR flash or SPI flash.

The library developed for ESP8266 modules includes most of the functionalities with some additional limitations due to the limitations of microcontrollers:

  • Tree there is no file tree. The files are placed flat in the file area. Instead, it is possible to use the “\” character in the file name to create a pseudo tree.
  • File name limited to 31 useful characters this is the second important limitation. The ‘\0’ character is reserved and automatically added at the end of the file name for compatibility with C language character strings. Warning, the file extension generally consumes 4 out of the 31 useful characters.
  • No warning message in case of error no error message will appear during compilation or at runtime if the limit of 32 characters is exceeded. If the program does not work as expected, be sure to check the file name.

Other useful limitations to know:

  • Space (s) or accented character (s) must not be used in the file name
  • There is no queue
  • The writing time is variable from one file to another
  • SPIFFS is for small flash memory devices, do not exceed 128MB of storage
  • There is no bad block detection mechanism

Discovery of the SPIFFS.h library, API and available methods

The SPIFFS.h library is a port of the official library for Arduino which is installed at the same time as the ESP32 SDK.

The proposed methods are almost identical to the FS.h library for ESP8266.

The following methods are not available

FS.h library APIEquivalent Method
SPIFFS.openDir(path)none
SPIFFS.info(fs_info)SPIFFS.totalBytes()

Returns the total number of bytes used by the SPIFFS file system.

SPIFFS.usedBytes()

Returns the space used by the specified file in bytes

To access the file system, all you have to do is declare it at the start of the sketch

#include "SPIFFS.h"

How to format a file name (path)?

SPIFFS does not manage the tree.

However, we can create a pseudo tree using the “/” character in the file name without exceeding the limit of 31 useful characters.

The file path must always start with the character “/”, for example /fichier.txt

The methods (API) of the SPIFFS.h library

SPIFFS.begin()

This method mounts the SPIFFS file system and must be called before any other FS method is used. Returns true if the file system was mounted successfully.

It is advisable to mount the file system in the setup

void setup() { 
  // Launch SPIFFS file system  
  if(!SPIFFS.begin()){ 
    Serial.println("An Error has occurred while mounting SPIFFS");  
  }
}

SPIFFS.format()

Format the file system. Returns true if formatting was successful. Attention, if files are present in the memory area, they will be irreversibly deleted.

if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
  return;
}

bool formatted = SPIFFS.format();
 if ( formatted ) {
  Serial.println("SPIFFS formatted successfully");
} else {
  Serial.println("Error formatting");
}

SPIFFS.open(path, option)

Open a file

path must be an absolute path starting with a forward slash (eg /dir/file_name.txt).

option is a string specifying the access mode. It can be

  • “r” read, read only
  • “r +” read and write. The pointer is positioned at the start of the file
  • “w” write, write. The existing content is deleted. The file is created if it does not exist
  • “w +” opens the file for reading and writing. The file is created if it does not exist, otherwise it is truncated. The pointer is positioned at the start of the file
  • “a” append, opens a file adding data. The file is created if it does not exist. The pointer is positioned at the end of the file if it already exists
  • “a +” append, opens a file adding data. The file is created if it does not exist. The pointer is positioned at the start of the file for reading and at the end of the file for writing (appending)

Returns the File object. To check if the file was opened successfully, use the Boolean operator.

Once the file is open, here are the methods that allow you to manipulate it

file.seek(offset, mode)

This function behaves like the fseek function of the C language. Depending on the value of mode, the pointer is positioned in the file like this

SeekSet position is set to offset bytes from the start

SeekCur current position is moved by offset bytes

SeekEnd position is set to shift bytes from end of file

The function returns true if the position was set successfully

file.position()

Returns the current position in the file in bytes.

file.size()

Returns the size of the file in bytes. Please note, it is not possible to know the size of a folder

File file = SPIFFS.open("/test.txt"); 
if(!file){ 
  Serial.println("Failed to open file for reading"); 
  return; 
} 
Serial.print("File size: "); 
Serial.println(file.size()); 
file.close();

file.name()

Returns the name of the file in a constant in the format const char *

file.close()

Close the file

Folder operations

file.isDirectory()

There is no difference between file and folder. The isDirectory() method lets you know if the file is a folder. It is not possible to know the size of a folder

dir.openNextFile()

Open following folder

SPIFFS.exists(path)

Returns true if a file with a given path exists, false otherwise.

SPIFFS.totalBytes()

Returns the total number of bytes used by the SPIFFS file system.

SPIFFS.usedBytes()

Returns the space used by the specified file in bytes

SPIFFS.remove(path)

Deletes the file based on its absolute path. Returns true if the file was deleted successfully.

SPIFFS.rename(pathFrom, pathTo)

Renames the file from pathFrom to pathTo. The paths must be absolute. Returns true if the file was renamed successfully.

SPIFFS.end()

Unmounts the filesystem

How to transfer files to the SPIFFS memory area?

It is possible to directly upload files to the SPIFFS file system using the plugin for the Arduino ESP32 Sketch Data Upload IDE.

esp32 spiffs data folder project structure

To do this, simply create a folder named data at the same level as the main Arduino project file. It is better to avoid creating subfolders.

This is because the SPIFFS file system does not manage the file tree. During the transfer, the files will be “flat”, ie the file will take the access path as name.

esp32 sketch data upload ide arduino

To learn more, read this tutorial which explains everything in detail.

Retrieve information from the SPIFFS and list of files

Here is a small example of code which allows you to retrieve information from the memory area as well as the list of files found in the memory area.

#include "SPIFFS.h" 

void listFilesInDir(File dir, int numTabs = 1);

void setup() {
    Serial.begin(112500);
 
    delay(500);
 
    Serial.println(F("Inizializing FS..."));
    if (SPIFFS.begin()){
        Serial.println(F("SPIFFS mounted correctly."));
    }else{
        Serial.println(F("!An error occurred during SPIFFS mounting"));
    }

    // Get all information of SPIFFS
 
    unsigned int totalBytes = SPIFFS.totalBytes();
    unsigned int usedBytes = SPIFFS.usedBytes();
 
    Serial.println("===== File system info =====");
 
    Serial.print("Total space:      ");
    Serial.print(totalBytes);
    Serial.println("byte");
 
    Serial.print("Total space used: ");
    Serial.print(usedBytes);
    Serial.println("byte");
 
    Serial.println();
 
    // Open dir folder
    File dir = SPIFFS.open("/");
    // List file at root
    listFilesInDir(dir);
}

void listFilesInDir(File dir, int numTabs) {
  while (true) {
 
    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files in the folder
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      listFilesInDir(entry, numTabs + 1);
    } else {
      // display zise for file, nothing for directory
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

void loop() {
 
} 

Open the Serial Monitor to view the occupancy, the available space is the SPIFFS files stored on the flash memory.

Inizializing FS...
SPIFFS mounted correctly.
File system info.
Total space:      1374476byte
Total space used: 502byte

    /test.txt       11

How to write to a file programmatically with SPIFFS.h

We saw how to create a file from a computer and then upload it from the Arduino IDE.

The SPIFFS.h library provides several simple methods for accessing and handling files from an Arduino program. You can use any of the methods listed above.

Add this code just after the file.close(); line

file = SPIFFS.open("/test.txt", "w");
if(!file){
  // File not found
  Serial.println("Failed to open test file");
  return;
} else {
  file.println("Hello From ESP32 :-)");
  file.close();
}

What does this code do?

This time, we open the file with the option “w” to indicate that we want to modify the file. Previous content will be erased

To write to a file, you can use the print() or println() methods. The println() method adds a newline. We will use it to create a data table for example.

Here, we update the previous content

file.println("Hello From ESP32 :-)");

Upload to see what’s going on

How to add data to a file programmatically?

To add data to a file, just open a file with the “a” (append) option to append data to the end of the file.

If the file does not exist, it will be automatically created.

Here is a small example that records a counter every second.

void loop(){
  File file = SPIFFS.open("/counter.txt", "a");
  if(!file){
    // File not found 
    Serial.println("Failed to open counter file");
    return;
  } else {
    counter+=1;
    file.println(counter);
    file.close();
  }
  delay(1000);
}

Updates

02/09/2020 First publication of the post

Click to rate this post!
[Total: 0 Average: 0]

Are you having a problem with this topic?

Maybe someone has already found the solution, visit the forum before asking your question
Ask your question

Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

Did you like this project ? Don't miss any more projects by subscribing to our weekly newsletter!

We will be happy to hear your thoughts

      Leave a Reply

      DIY Projects