如何生成唯一文件名?附ESP8266/NodeMCU配置文件写入代码
生成唯一文件名的实用方案(针对ESP8266/NodeMCU enduser_setup场景)
针对你提到的ESP8266/NodeMCU enduser_setup模块写入配置文件的场景,要生成唯一文件名避免覆盖已有文件,这里有几个接地气的实现方案,结合你的代码场景来拆解:
1. 基于系统启动时间戳生成
这是最简单的方案,不需要额外依赖,利用ESP8266的system_get_time()获取系统启动后的毫秒数,拼接在文件名后,确保每次生成的文件名唯一(除非极端情况同一毫秒内重复调用,但嵌入式场景下概率极低)。
修改你的代码示例:
static int enduser_setup_write_file_with_extra_configuration_data( char * configuration_string, int configuration_length ) { int p_file = 0; lua_State *L = NULL; char filename[64]; // 预留足够的文件名缓冲区 // 生成带时间戳的唯一文件名 snprintf(filename, sizeof(filename), "enduser_custom_params_%lu.json", system_get_time()); ENDUSER_SETUP_DEBUG("enduser: opening %s for write", filename); // 打开文件准备写入 p_file = vfs_open(filename, "w"); if (p_file == 0) { ENDUSER_SETUP_DEBUG("enduser: failed to open file for writing"); return -1; // 处理文件打开失败的情况 } // 写入配置数据 vfs_write(p_file, configuration_string, configuration_length); // 记得关闭文件 vfs_close(p_file); ENDUSER_SETUP_DEBUG("enduser: successfully wrote configuration to %s", filename); return 0; }
2. 递增序号生成
如果需要文件名更规整(比如按序号排序),可以检查已有文件的序号,从1开始递增,直到找到一个不存在的文件名。这个方案适合需要保留历史配置文件的场景。
示例代码片段:
static int enduser_setup_write_file_with_extra_configuration_data( char * configuration_string, int configuration_length ) { int p_file = 0; lua_State *L = NULL; char filename[64]; int i = 1; // 循环查找可用的序号文件名 while(1) { snprintf(filename, sizeof(filename), "enduser_custom_params_%d.json", i); // 尝试以只读模式打开,判断文件是否存在 p_file = vfs_open(filename, "r"); if (p_file == 0) { // 文件不存在,就是我们要的文件名 break; } // 文件存在,关闭后继续递增序号 vfs_close(p_file); i++; } ENDUSER_SETUP_DEBUG("enduser: opening %s for write", filename); p_file = vfs_open(filename, "w"); if (p_file == 0) { ENDUSER_SETUP_DEBUG("enduser: failed to open file for writing"); return -1; } vfs_write(p_file, configuration_string, configuration_length); vfs_close(p_file); ENDUSER_SETUP_DEBUG("enduser: successfully wrote configuration to %s", filename); return 0; }
3. 结合MAC地址+时间戳生成
如果你的场景需要跨设备的全局唯一文件名(比如多个设备生成的文件上传到同一服务器),可以结合ESP8266的唯一MAC地址和时间戳来生成,确保绝对不重复。
示例代码片段:
#include "esp_common.h" // 确保包含wifi相关头文件 static int enduser_setup_write_file_with_extra_configuration_data( char * configuration_string, int configuration_length ) { int p_file = 0; lua_State *L = NULL; char filename[64]; uint8_t mac[6]; // 获取设备的STA模式MAC地址 wifi_get_macaddr(STATION_IF, mac); // 拼接MAC地址和时间戳生成唯一文件名 snprintf(filename, sizeof(filename), "enduser_custom_params_%02x%02x%02x%02x%02x%02x_%lu.json", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], system_get_time()); ENDUSER_SETUP_DEBUG("enduser: opening %s for write", filename); p_file = vfs_open(filename, "w"); if (p_file == 0) { ENDUSER_SETUP_DEBUG("enduser: failed to open file for writing"); return -1; } vfs_write(p_file, configuration_string, configuration_length); vfs_close(p_file); ENDUSER_SETUP_DEBUG("enduser: successfully wrote configuration to %s", filename); return 0; }
几个注意点
- 文件名缓冲区要足够大,但不要浪费内存,64字符对于嵌入式场景完全足够。
- 如果需要兼容原始文件名,可以先检查
enduser_custom_parameters.json是否存在,存在则生成唯一文件名,不存在则直接使用原始文件名。 - 记得在文件操作完成后调用
vfs_close(),避免资源泄漏。
内容的提问来源于stack exchange,提问作者LA_
相关产品推荐
相关产品推荐

