ESP32 IDF 4.1下readdir返回全0xFF 8.3文件名是否属于正常现象
问题1:该现象是否说明文件系统存在错误?
不属于文件系统损坏,是ESP-IDF 4.1版本FatFs适配层的已知行为,原因如下:
- FAT文件系统中,已删除的目录项首字节会被标记为
0xE5(八进制表示为\357),未使用的目录项首字节会被标记为0xFF(八进制表示为\377),正常情况下文件系统驱动应该主动过滤这类无效目录项,不会返回给上层应用 - ESP-IDF 4.1版本的
vfs_fat层实现存在缺陷,没有在readdir接口中过滤这类无效目录项,直接将Flash上存储的原始目录项透传了出来 - 你观察到
stat()返回和上一个有效文件一致的结果,也是该版本适配层的缺陷导致:内部的stat缓存结构体没有在读取到无效目录项时重置,直接复用了上一次有效查询的结果
问题2:常规readdir目录遍历操作是否需要主动过滤这类无效条目?
在ESP-IDF 4.1版本上进行FatFs目录遍历,必须主动过滤无效条目,过滤规则如下:
- 首字节为
\377(0xFF)或者\357(0xE5)的条目直接跳过 - 同时还要过滤
.(当前目录)和..(上级目录)两个特殊目录项 - 如果你升级到ESP-IDF 4.2及以上版本,该缺陷已经被修复,不需要额外做这类底层过滤逻辑
优化后的遍历代码示例:
struct dirent * dirent; while((dirent = readdir(dir)) != nullptr) { // 过滤无效条目 if (dirent->d_name[0] == '\377' || dirent->d_name[0] == '\357') { continue; } // 过滤特殊目录 if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { continue; } ESP_LOGI("ConfigServer", "Found %s, id %d, type %d", dirent->d_name, dirent->d_ino, dirent->d_type); // 处理有效文件/目录逻辑 } closedir(dir);
内容的提问来源于stack exchange,提问作者Brian A. Henning
相关产品推荐
相关产品推荐

