文件操作说明

[English]

文件操作概述

文件操作是对存储介质上的数据进行读取、写入、修改和管理的行为,是程序与外部数据交互的基础手段。通过文件操作,应用程序可以保存状态、日志数据或其他信息,并在需要时重新读取,同时开发者无需关注底层闪存的物理存储结构或擦写逻辑,只需按照常规文件操作流程即可实现数据存取和管理。

文件操作接口

POSIX(Portable Operating System Interface)和 C 标准库提供了统一的文件操作接口,这类接口的优势包括:

  • 跨平台兼容性强:POSIX 和 C 标准库接口在不同操作系统上基本一致,有利于代码移植。

  • 功能丰富:支持文件打开、读取、写入、关闭、定位、权限控制等多种操作。

  • 成熟稳定:接口经过长期使用,易于调试和维护。

除了 POSIX 和 C 标准库外,常见的文件操作方式还有:

  • 专用文件系统 API:如 SPIFFS、LittleFS 提供的接口,针对嵌入式闪存优化,支持文件系统完整性检查、垃圾回收等。

  • 存储抽象库:如 NVS 提供键值对存储接口,更适合小型配置数据存储。

相比之下,POSIX/C 标准库文件操作简单,接口统一,适合多种存储设备,逻辑清晰,但开销较大,对闪存的擦写管理不如专用文件系统优化,直接使用可能增加损耗。

文件系统与存储设备

不同类型的存储设备和文件系统对数据操作的支持方式各不相同。以下内容仅说明当前示例中涉及的存储设备和文件系统,帮助开发者理解它们的适配关系。

  1. 存储设备:是实际的硬件介质,用于存放数据。

片上闪存(Flash):适合存储小规模、关键数据,擦写次数有限,需要注意寿命管理。 SD 卡:容量大,通常使用 FAT 文件系统,读写兼容性好,可直接读写文件。适合存储大量文件数据。

  1. 文件系统:是存储设备上的数据管理和访问层,实现文件的组织和操作接口。进一步说明可参考 文件系统

SPIFFS:通过 SPIFFS 提供的接口可挂载为 POSIX 风格文件系统,因此 POSIX 文件操作可直接在 SPIFFS 上使用,但要注意闪存寿命。 FAT 文件系统:提供传统文件操作接口,POSIX/C 文件操作可直接使用,适合大容量数据存储,通常用于 SD 卡。 NVS(非易失性存储):挂载在片上闪存上,以键值对形式管理数据,不是传统文件系统,POSIX 文件操作不可直接使用,需要通过相关 API进行读写。

  1. 操作接口

  • 对于 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

模式

模式说明

文件存在

文件不存在

"r"

只读模式

打开文件

返回 NULL,不会创建新文件

"w"

只写模式

打开文件并清空内容,会覆盖已存在的文件

创建新文件

"a"

追加模式

打开文件,指针指向末尾,不会覆盖原文件内容

创建新文件

"r+"

读写模式

打开文件

返回 NULL,不会创建新文件

"w+"

读写模式

打开文件并清空内容,会覆盖已存在的文件

创建新文件

"a+"

读写追加模式

打开文件,指针指向末尾,不会覆盖原文件内容

创建新文件