ESP32 Arduino: Listing files in a SPIFFS file system specific path

In this tutorial we will learn how to list the files contained in a directory on the SPIFFS file system of the ESP32. The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board.

Introduction

In this tutorial we will learn how to list the files contained in a directory on the SPIFFS file system of the ESP32. We will be using the Arduino core to program the ESP32.

For an explanation on how to list all the files from the SPIFFS file system, please check this previous tutorial.

Recall from the mentioned previous tutorial that SPIFFS is a flat file system, which means that directories have no physical representation. So, there are only files with names that contain the full path of the files. For example, a file called “test.txt” inside a folder called “/fold” is represented by a file with the name “/fold/test.txt” on this file system.

For this tutorial, we will use the same folder hierarchy that we have used in the previous one (folders represented in green and files in blue):

|– emptyFolder
|– folder1
|– — other_file.txt
|– — nested
|– — — nested.txt
|– folder2
|– — some_file.txt
|– file.txt

You can create this folder hierarchy inside a data folder located in your Arduino sketch directory and upload it using the Arduino IDE SPIFFS plugin. You can follow a detailed tutorial on how to use this plugin here.

As mentioned before, this file system doesn’t have a physical representation of directories. Thus, the path in which the file is located is reflected in its name. So, the procedure we will use to list all the files in a given directory will list all the files that start with the same name of that directory.

For example, taking in consideration the folder hierarchy we will use, if we list all the files located in the “/folder1” directory, we will both obtain the “/folder1/other_file.txt” and the “/folder1/nested/nested.txt” files, since both have a name starting with “/folder1“.

If we want to obtain a file contained in a nested directory, then we need to specify the whole path to that directory. So, if we only want to obtain the file “/folder1/nested/nested.txt“, we should use the “/folder1/nested” path.

Taking this complexity in consideration and the fact that the whole file name cannot be bigger than 31 characters, we should be careful when designing the folder structure of the SPIFFS file system that will exist in the ESP32.

The code shown here is adapted from the Arduino core SPIFFS example, which I really encourage you to try. It’s a very complete example of what can be done using SPIFFS.

The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board.

The code

We will start the code by including the SPIFFS.h library, like we have been doing in previous tutorials where we interacted with this file system. As before, this will give us access to the SPIFFS extern variable, which we will use to interact with the file system.

#include "SPIFFS.h"

Then, we will declare a function called listDir which will allow us to print to the serial port the files inside a given directory. The function will receive as input a string with the directory for which we want to list the files.

void listDir(char * dir){
// function implementation
}

The implementation of this function will be very similar to the code we used on the previous tutorial tutorial where we listed all the files from the SPIFFS file system. Nonetheless, this time, the path of our directory will be the argument of the listDir function, which will allow us to list the files in the directory we want.

So, the first thing we will do is calling the open method on the SPIFFS object, passing as input the directory we want to open. Recall that directories don’t have a physical representation in our file system and thus this is just a procedure that we follow to start iterating the files. This method call will return a File object representing the directory.

File root = SPIFFS.open(dir);

Then, to get the first file in that directory, we will call the openNextFile method on our File object. This will return another File object, this time representing an actual File (if there are any files on that directory).

File file = root.openNextFile();

Then, we will do a while loop, which will break when we open a non-existing file (recall that the File class overrides the C++ bool operator, which allow us to use the object as a Boolean in conditions). Naturally, when this happens, it means that there are no more files in the directory.

In each iteration of the loop, we will simply print the name of the file and then try to obtain the next file with a call to the openNextFile method. The full listDir function can be seen below and it already contains this loop.

void listDir(char * dir){

  File root = SPIFFS.open(dir);

  File file = root.openNextFile();

  while(file){

      Serial.print("FILE: ");
      Serial.println(file.name());

      file = root.openNextFile();
  }

}

Moving on to the setup function, we will start by opening a serial connection, so the listDir function can print the names of the files.

Serial.begin(115200);

Then we will mount the file system, so we can start using it.

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

Then, we will call the listDir function and pass as input the directories we have in our file system structure. Note that, as already mentioned, when we have nested folders we need to pass the whole path of that folder and not just the its relative path.

Serial.println("\n----DIR: /folder1");
listDir("/folder1");

Serial.println("\n----DIR: /folder2:");
listDir("/folder2");

Serial.println("\n----DIR: /folder1/nested:");
listDir("/folder1/nested");

So, for the nested folder we have in our file system, if we just pass the path “/nested” rather than “/folder1/nested“, nothing will be found because no file name starts with “/nested“. We will also check this use case to confirm the behavior.

Serial.println("\n----DIR: /nested:");
listDir("/nested");

The final source code can be seen below.

#include "SPIFFS.h"

void listDir(char * dir){

  File root = SPIFFS.open(dir);

  File file = root.openNextFile();

  while(file){

      Serial.print("FILE: ");
      Serial.println(file.name());

      file = root.openNextFile();
  }

}

void setup() {

  Serial.begin(115200);

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

  Serial.println("\n----DIR: /folder1");
  listDir("/folder1");

  Serial.println("\n----DIR: /folder2:");
  listDir("/folder2");  

  Serial.println("\n----DIR: /folder1/nested:");
  listDir("/folder1/nested");

  Serial.println("\n----DIR: /nested:");
  listDir("/nested");

}

void loop() {}

Testing the code

To test the code, assuming that you already uploaded all the files to your file system, simply compile it and upload it to your ESP32.

Then, when the procedure finishes, open the Arduino IDE serial monitor. You should get an output similar to figure 1.

As can be seen, when we list the files in the directory “/folder1”, all the files it contains get printed. This is true even for the file that is nested in another directory inside “/folder1”. The reason is that this approach will show all the files that have a name starting with “/folder1“, no matter if they contain more “/” characters in their name.

For the remaining folders, the files they contain are also correctly listed, as can be observed in the image. For the particular case of the “/nested” directory, nothing gets printed because no file name starts with “/nested“.

ESP32 Arduino listing directories in the SPIFFS file system

Figure 1 – Content of the directories tested.

Related Posts

Leave a Reply