文件操作说明
文件操作概述
文件操作是对存储介质上的数据进行读取、写入、修改和管理的行为,是程序与外部数据交互的基础手段。通过文件操作,应用程序可以保存状态、日志数据或其他信息,并在需要时重新读取,同时开发者无需关注底层闪存的物理存储结构或擦写逻辑,只需按照常规文件操作流程即可实现数据存取和管理。
文件操作接口
POSIX(Portable Operating System Interface)和 C 标准库提供了统一的文件操作接口,这类接口的优势包括:
跨平台兼容性强:POSIX 和 C 标准库接口在不同操作系统上基本一致,有利于代码移植。
功能丰富:支持文件打开、读取、写入、关闭、定位、权限控制等多种操作。
成熟稳定:接口经过长期使用,易于调试和维护。
除了 POSIX 和 C 标准库外,常见的文件操作方式还有:
专用文件系统 API:如 SPIFFS、LittleFS 提供的接口,针对嵌入式闪存优化,支持文件系统完整性检查、垃圾回收等。
存储抽象库:如 NVS 提供键值对存储接口,更适合小型配置数据存储。
相比之下,POSIX/C 标准库文件操作简单,接口统一,适合多种存储设备,逻辑清晰,但开销较大,对闪存的擦写管理不如专用文件系统优化,直接使用可能增加损耗。
文件系统与存储设备
不同类型的存储设备和文件系统对数据操作的支持方式各不相同。以下内容仅说明当前示例中涉及的存储设备和文件系统,帮助开发者理解它们的适配关系。
存储设备:是实际的硬件介质,用于存放数据。
片上闪存(Flash):适合存储小规模、关键数据,擦写次数有限,需要注意寿命管理。 SD 卡:容量大,通常使用 FAT 文件系统,读写兼容性好,可直接读写文件。适合存储大量文件数据。
文件系统:是存储设备上的数据管理和访问层,实现文件的组织和操作接口。进一步说明可参考 文件系统。
SPIFFS:通过 SPIFFS 提供的接口可挂载为 POSIX 风格文件系统,因此 POSIX 文件操作可直接在 SPIFFS 上使用,但要注意闪存寿命。 FAT 文件系统:提供传统文件操作接口,POSIX/C 文件操作可直接使用,适合大容量数据存储,通常用于 SD 卡。 NVS(非易失性存储):挂载在片上闪存上,以键值对形式管理数据,不是传统文件系统,POSIX 文件操作不可直接使用,需要通过相关 API进行读写。
操作接口
对于 SPIFFS 或 FAT 文件系统,可以直接使用常规文件操作函数。
对于 NVS,需要使用专门的键值 API 进行读写。
文件操作方式
创建文件并写入
调用
fopen()
以指定模式(此处为只写w
模式),打开指定文件。如果文件不存在则创建新文件。调用
fprintf()
将内容写入目标文件。调用
fclose()
关闭文件。
检查文件并重命名
调用
stat()
并传入重命名目标文件路径,检查该路径终点文件是否存在,以判断是否需要先删除文件以避免重命名冲突。如存在,则调用
unlink()
删除该文件,以避免重命名冲突。调用
rename()
将原始文件重命名。
读取文件
调用
fopen()
以指定模式(此处为只读r
模式),打开指定文件。如果文件不存在将返回NULL
。调用
fgets()
读取文件内容。如需要打印,需要处理换行符。调用
fclose()
关闭文件。
处理并打印读取内容
当调用 fgets()
从文件中读取一行数据时,字符串末尾通常会包含换行符 \n
。为了打印或后续处理方便,需去除该换行符。
调用
strchr()
在目标字符数组中查找第一个出现的换行符,并返回指向换行符位置的指针,如果未找到则返回NULL
。判断是否查找到换行符,如找到,则将换行符替换为字符串结束符
\0
,从而截断字符串,去掉行末的换行。打印日志,输出相关信息,用于调试或观察读取结果。
卸载文件系统
在不再需要访问文件系统时,应调用卸载操作,将 Spiffs 从虚拟文件系统中解除挂载。这一操作可释放系统资源,防止内存或文件句柄泄漏,同时保证系统状态清晰,适合在程序结束或切换文件系统时执行。
调用
esp_vfs_spiffs_unregister()
卸载分区,释放资源。
文件打开模式
在标准 C 库中,fopen() 的行为取决于打开文件时指定的模式 _type
。
模式 |
模式说明 |
文件存在 |
文件不存在 |
---|---|---|---|
|
只读模式 |
打开文件 |
返回 |
|
只写模式 |
打开文件并清空内容,会覆盖已存在的文件 |
创建新文件 |
|
追加模式 |
打开文件,指针指向末尾,不会覆盖原文件内容 |
创建新文件 |
|
读写模式 |
打开文件 |
返回 |
|
读写模式 |
打开文件并清空内容,会覆盖已存在的文件 |
创建新文件 |
|
读写追加模式 |
打开文件,指针指向末尾,不会覆盖原文件内容 |
创建新文件 |