Filesystem Spiffs  ESP8266 Documentation
Filesystem Spiffs  ESP8266 Documentation
Filesystem
Flash layout
Even though file system is stored on the same flash chip as the program, programming new
sketch will not modify file system contents. This allows to use file system to store sketch
data, configura on files, or content for Web server.
|--------------|-------|---------------|--|--|--|--|--|
^ ^ ^ ^ ^
Sketch OTA update File system EEPROM WiFi config (SDK)
File system size depends on the flash chip size. Depending on the board which is selected in
IDE, you have the following op ons for flash size:
Generic module 2M 1M
Olimex MOD-WIFI-ESP8266(-DEV) 2M 1M
Note: to use any of file system func ons in the sketch, add the following include to the
sketch:
SPIFFS is the original filesystem and is ideal for space and RAM constrained applica ons that
u lize many small files and care about sta c and dynamic wear levelling and don’t need true
directory support. Filesystem overhead on the flash is minimal as well.
Li leFS is recently added and focuses on higher performance and directory support, but has
higher filesystem and per-file overhead (4K minimum vs. SPIFFS’ 256 byte minimum file
alloca on unit).
They share a compa ble API but have incompa ble on-flash implementa ons, so it is
important to choose one or the per project as a emp ng to mount a SPIFFS volume under
Li leFS may result in a format opera on and definitely will not preserve any files, and vice-
versa.
The actual File and Dir objects returned from either filesystem behave in the same
manner and documenta on is applicable to both. To convert most applica ons from SPIFFS
to Li leFS simply requires changing the SPIFFS.begin() to LittleFS.begin() and
SPIFFS.open() to LittleFS.open() with the rest of the code remaining untouched.
SDFS and SD
/
FAT filesystems are supported on the ESP8266 using the old Arduino wrapper “SD.h” which
wraps the “SDFS.h” filesystem transparently.
Any commands discussed below pertaining to SPIFFS or Li leFS are applicable to SD/SDFS.
For legacy applica ons, the classic SD filesystem may con nue to be used, but for new
applica ons, directly accessing the SDFS filesystem is recommended as it may expose
addi onal func onality that the old Arduino SD filesystem didn’t have.
Note that in earlier releases of the core, using SD and SPIFFS in the same sketch was
complicated and required the use of NO_FS_GLOBALS . The current design makes SD, SDFS,
SPIFFS, and Li leFS fully source compa ble and so please remove any NO_FS_GLOBALS
First, behind the scenes, SPIFFS does not support directories, it just stores a “flat” list of files.
But contrary to tradi onal filesystems, the slash character '/' is allowed in filenames, so the
func ons that deal with directory lis ng (e.g. openDir("/website") ) basically just filter the
filenames and keep the ones that start with the requested prefix ( /website/ ). Prac cally
speaking, that makes li le difference though.
Second, there is a limit of 32 chars in total for filenames. One '\0' char is reserved for C
string termina on, so that leaves us with 31 usable characters.
Combined, that means it is advised to keep filenames short and not use deeply nested
directories, as the full path of each file (including directories, '/' characters, base name, dot
and extension) has to be 31 chars at a maximum. For example, the filename
/website/images/bird_thumbnail.jpg is 34 chars and will cause some problems if used, for
example in exists() or in case another file starts with the same first 31 characters.
Warning: That limit is easily reached and if ignored, problems might go unno ced because no
error message will appear at compila on nor run me.
For more details on the internals of SPIFFS implementa on, see the SPIFFS readme file.
Opening files in subdirectories requires specifying the complete path to the file (i.e.
open("/sub/dir/file.txt"); ). Subdirectories are automa cally created when you a empt to
create a file in a subdirectory, and when the last file in a subdirectory is removed the
subdirectory itself is automa cally deleted. This is because there was no mkdir() method in
the exis ng SPIFFS filesystem.
Unlike SPIFFS, the actual file descriptors are allocated as requested by the applica on, so in
low memory condi ons you may not be able to open new files. Conversely, this also means
that only file descriptors used will actually take space on the heap.
Because there are directories, the openDir method behaves differently than SPIFFS.
Whereas SPIFFS will return files in “subdirectories” when you traverse a Dir::next()
(because they really aren’t subdirs but simply files with “/”s in their names), Li leFS will only
return files in the specific subdirectory. This mimics the POSIX behavior for directory
traversal most C programmers are used to.
Warning: Due to the move from the obsolete esptool-ck.exe to the supported esptool.py
upload tool, upgraders from pre 2.5.1 will need to update the ESP8266FS tool referenced
below to 0.5.0 or later. Prior versions will fail with a “esptool not found” error because they
don’t know how to use esptool.py.
SPIFFSConfig cfg;
cfg.setAutoFormat(false);
SPIFFS.setConfig(cfg);
This method allows you to configure the parameters of a filesystem before moun ng. All
filesystems have their own *Config (i.e. SDFSConfig or SPIFFSConfig with their custom set
of op ons. All filesystems allow explicitly enabling/disabling forma ng when mounts fail. If
you do not call this setConfig method before perforing begin() , you will get the
filesystem’s default behavior and configura on. By default, SPIFFS will autoformat the
filesystem if it cannot mount it, while SDFS will not.
begin
SPIFFS.begin()
or LittleFS.begin()
This method mounts file system. It must be called before any other FS APIs are used. Returns
true if file system was mounted successfully, false otherwise. With no op ons it will format
SPIFFS if it is unable to mount it on the first try.
Note that both methods will automa cally format the filesystem if one is not detected. This
means that if you a empt a SPIFFS.begin() on a Li leFS filesystem you will lose all data on
that filesystem, and vice-versa.
end
SPIFFS.end()
or LittleFS.end()
/
This method unmounts the file system. Use this method before upda ng the file system using
OTA.
format
SPIFFS.format()
or LittleFS.format()
Formats the file system. May be called either before or a er calling begin . Returns true if
forma ng was successful.
open
SPIFFS.open(path, mode)
or LittleFS.open(path, mode)
Opens a file. path should be an absolute path star ng with a slash (e.g. /dir/filename.txt ).
mode is a string specifying access mode. It can be one of “r”, “w”, “a”, “r+”, “w+”, “a+”. Meaning
of these modes is the same as for fopen C func on.
Returns File object. To check whether the file was opened successfully, use the boolean
operator.
/
File f = SPIFFS.open("/f.txt", "w");
if (!f) {
Serial.println("file open failed");
}
exists
SPIFFS.exists(path)
or LittleFS.exists(path)
mkdir
LittleFS.mkdir(path)
rmdir
LittleFS.rmdir(path)
openDir
SPIFFS.openDir(path)
or LittleFS.openDir(path)
Opens a directory given its absolute path. Returns a Dir object. Please note the previous
discussion on the difference in behavior between Li leFS and SPIFFS for this call.
remove
SPIFFS.remove(path)
or LittleFS.remove(path)
Deletes the file given its absolute path. Returns true if file was deleted successfully.
/
rename
SPIFFS.rename(pathFrom, pathTo)
or LittleFS.rename(pathFrom, pathTo)
Renames file from pathFrom to pathTo . Paths must be absolute. Returns true if file was
renamed successfully.
gc
SPIFFS.gc()
check
SPIFFS.begin();
SPIFFS.check();
Only implemented in SPIFFS. Performs an in-depth check of the filesystem metadata and
correct what is repairable. Not normally needed, and not guaranteed to actually fix anything
should there be corrup on.
info
FSInfo fs_info;
SPIFFS.info(fs_info);
or LittleFS.info(fs_info);
Fills FSInfo structure with informa on about the file system. Returns true if successful,
false otherwise.
/
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
This is the structure which may be filled using FS::info method. - totalBytes — total size of
useful data on the file system - usedBytes — number of bytes used by files - blockSize —
filesystem block size - pageSize — filesystem logical page size - maxOpenFiles — max
number of files which may be open simultaneously - maxPathLength — max file name length
(including one byte for zero termina on)
info64
FSInfo64 fsinfo;
SD.info(fsinfo);
or LittleFS(fsinfo);
Performs the same opera on as info but allows for repor ng greater than 4GB for
filesystem size/used/etc. Should be used with the SD and SDFS filesystems since most SD
cards today are greater than 4GB in size.
setTimeCallback(time_t (*cb)(void))
time_t myTimeCallback() {
return 1455451200; // UNIX timestamp
}
void setup () {
LittleFS.setTimeCallback(myTimeCallback);
...
// Any files will now be made with Pris' incept date
}
The SD, SDFS, and Li leFS filesystems support a file mestamp, updated when the file is
opened for wri ng. By default, the ESP8266 will use the internal me returned from
time(NULL) (i.e. local me, not UTC, to conform to the exis ng FAT filesystem), but this can
be overridden to GMT or any other standard you’d like by using setTimeCallback() . If your
app sets the system me using NTP before file opera ons, then you should not need to use
this func on. However, if you need to set a specific me for a file, or the system clock isn’t
correct and you need to read the me from an external RTC or use a fixed me, this call
allows you do to so.
/
In general use, with a func oning time() call, user applica ons should not need to use this
func on.
next
Returns true while there are files in the directory to iterate over. It must be called before
calling fileName() , fileSize() , and openFile() func ons.
fileName
Returns the name of the current file pointed to by the internal iterator.
fileSize
Returns the size of the current file pointed to by the internal iterator.
fileTime
Returns the me_t write me of the current file pointed to by the internal iterator.
fileCreationTime
Returns the me_t crea on me of the current file pointed to by the internal iterator.
isFile
Returns true if the current file pointed to by the internal iterator is a File.
isDirectory
/
Returns true if the current file pointed to by the internal iterator is a Directory.
openFile
This method takes mode argument which has the same meaning as for
SPIFFS/LittleFS.open() func on.
rewind
setTimeCallback(time_t (*cb)(void))
Sets the me callback for any files accessed from this Dir object via openNextFile. Note that
the SD and SDFS filesystems only support a filesystem-wide callback and calls to
Dir::setTimeCallback may produce unexpected behavior.
File object
SPIFFS/LittleFS.open() and dir.openFile() func ons return a File object. This object
supports all the func ons of Stream, so you can use readBytes , findUntil , parseInt ,
println , and all other Stream methods.
There are also some func ons which are specific to File object.
seek
file.seek(offset, mode)
This func on behaves like fseek C func on. Depending on the value of mode , it moves
current posi on in a file as follows:
position
file.position()
/
Returns the current posi on inside the file, in bytes.
size
file.size()
name
Returns short (no-path) file name, as const char* . Convert it to String for storage.
fullName
// Filesystem:
// testdir/
// file1
Dir d = LittleFS.openDir("testdir/");
File f = d.openFile("r");
// f.name() == "file1", f.fullName() == "testdir/file1"
getLastWrite
Returns the file last write me, and only valid for files opened in read-only mode. If a file is
opened for wri ng, the returned me may be indeterminate.
getCreationTime
isFile
isDirectory /
bool amIADir = file.isDir();
Returns true if this File points to a directory (used for emula on of the SD.* interfaces with
the openNextFile method).
close
file.close()
Close the file. No other opera ons should be performed on File object a er close func on
was called.
Opens the next file in the directory pointed to by the File. Only valid when
File.isDirectory() == true .
Resets the openNextFile pointer to the top of the directory. Only valid when
File.isDirectory() == true .
setTimeCallback(time_t (*cb)(void))
Sets the me callback for this specific file. Note that the SD and SDFS filesystems only
support a filesystem-wide callback and calls to Dir::setTimeCallback may produce
unexpected behavior.
/
/