目的
文件相关操作在上位机编程中十分常用,在单片机上就相对少些,不过随着现在单片机性能越来越强,文件的使用也变得越来越多了。
常用方法说明
文件操作相关方法
-
size_t write(uint8_t)
size_t write(const uint8_t *buf, size_t size)
向文件中写入数据,该操作会移动文件指针; -
int available()
返回当前指针下可读取字节数; -
int read()
size_t read(uint8_t* buf, size_t size)
size_t readBytes(char *buffer, size_t length)
读取数据,该操作会移动文件指针; -
int peek()
在不移动文件指针的情况下读取一个字节数据; -
bool seek(uint32_t pos, SeekMode mode)
bool seek(uint32_t pos)
移动文件指针,mode可选SeekSet
、SeekCur
、SeekEnd
,分别为正常移动、移动到文件头、移动到文件尾; -
size_t position()
返回当前文件指针位置; -
size_t size()
返回当前文件的大小; -
void close()
关闭当前文件; -
operator bool()
返回当前文件是否有效; -
time_t getLastWrite()
返回最后修改文件时间; -
const char* name()
返回当前文件名 -
boolean isDirectory(void)
返回当前文件是否为目录; -
File openNextFile(const char* mode = FILE_READ)
打开下一个文件; -
void rewindDirectory(void)
返回到目录中首文件位置; -
另外也可以使用print等方法;
文件系统通用方法
-
File open(const char* path, const char* mode = FILE_READ)
File open(const String& path, const char* mode = FILE_READ)
打开一个文件,输入参数分别为路径,打开方式;
mode可选FILE_READ
、FILE_WRITE
、FILE_APPEND
,即"r"
、"w"
、"a"
,只读模式、写入模式、追加模式;
只读模式:打开一个文件用于读取,指针位于文件头;
写入模式:打开一个文件用于写入,指针位于文件头,如果文件不存在则建立文件;
追加模式:打开一个文件用于写入,指针位于文件尾; -
bool exists(const char* path)
bool exists(const String& path)
检查文件或路径是否存在; -
bool remove(const char* path)
bool remove(const String& path)
移除文件; -
bool rename(const char* pathFrom, const char* pathTo)
bool rename(const String& pathFrom, const String& pathTo)
重命名文件,依次输入旧的、新的包含完整文件名的路径; -
bool mkdir(const char *path)
bool mkdir(const String &path)
创建目录; -
bool rmdir(const char *path)
bool rmdir(const String &path)
删除目录;
SPIFFS文件系统
-
bool begin(bool formatOnFail=false, const char * basePath="/spiffs", uint8_t maxOpenFiles=10)
挂载文件系统,输入参数分别为当挂载失败是否格式化、挂载点、文件最大同时打开数; -
bool format()
格式化文件系统; -
size_t totalBytes()
返回文件系统总字节数; -
size_t usedBytes()
返回文件系统已用字节数; -
void end()
取消挂载;
使用示例
可以使用下面代码进行简单测试:
//引用相关库
#include "FS.h"
#include "SPIFFS.h"
void setup()
{
Serial.begin(115200);
Serial.println();
//挂载文件系统
if (SPIFFS.begin(true))
{
Serial.println("SPIFFS文件系统挂载成功!");
}
//打开/建立 并写入数据
File file = SPIFFS.open("/test.txt", FILE_WRITE);
if (file)
{
Serial.println("打开/建立 根目录下 test.txt 文件!");
}
char data[] = "hello world\r\n";
file.write((uint8_t *)data, strlen(data));
file.close();
//重命名文件
if (SPIFFS.rename("/test.txt", "/retest.txt"))
{
Serial.println("test.txt 重命名为 retest.txt !");
}
//读取文件数据
file = SPIFFS.open("/retest.txt", FILE_READ);
if (file)
{
Serial.print("文件内容是:");
while (file.available())
{
Serial.print((char)file.read());
}
}
//打印SPIFFS文件系统信息
Serial.printf("SPIFFS文件系统总大小是: %d (字节)\n", SPIFFS.totalBytes());
Serial.printf("SPIFFS文件系统已用大小是: %d (字节)\n", SPIFFS.usedBytes());
}
void loop()
{
}
将上面代码烧录进模块中,Partition Scheme
选择Defaule 4MB with spiffs(1.2MB APP/1.5MB SPIFFS)
,烧录成功后可以看到下面输出:
- 在初次使用SPIFFS时调用
SPIFFS.begin()
会报上面错误信息,因为并不存在SPIFFS,挂载失败;在上面代码中begin方法第一个参数传入了true,所以在挂载失败时会进行格式化,然后重新挂载;格式化比较花时间,上图中可以看到将近花了20秒时间。 - 文件系统和其中的文件都是固化在存储器中的,可以通过改写上面代码进行测试。
- 上面示例只是基本的使用测试,很多方面都不完善,对于文件操作来说比较重要的是检查文件系统或文件对象是否可用、是否规范,这个可以参考下面链接中包含的例程,例程中各个关键点的检查都很完善。
总结
文件系统是非常常用到的功能,使用起来也不是特别复杂,毕竟常用的动作就那些,更多内容可以参考如下:
https://github.com/espressif/arduino-esp32/tree/master/libraries/FS
https://github.com/espressif/arduino-esp32/tree/master/libraries/SPIFFS
https://github.com/espressif/arduino-esp32/tree/master/libraries/FFat (FAT文件系统)