macOS下使用C/C++快速获取文件正确大小写名称的方法是什么?
macOS下获取文件实际大小写名称的最优C/C++实现方案
最快实现方案:调用POSIX realpath 接口
该方案开发成本最低,性能可满足绝大多数场景需求。macOS下的realpath实现会直接从文件系统元数据读取路径的实际大小写,不需要枚举父目录条目。
代码示例
#include <stdlib.h> #include <stdio.h> char* get_actual_path_case(const char* input_path) { // realpath自动分配返回值内存,调用方需后续free释放 return realpath(input_path, NULL); } // 调用示例 int main() { char* actual_path = get_actual_path_case("/Users/xxx/a.txt"); if (actual_path) { printf("实际路径:%s\n", actual_path); free(actual_path); } return 0; }
如果仅需要获取最后一段文件名,从返回的全路径中截取末尾段即可。
性能最优方案:使用BSD原生 getattrlist 系统调用
如果只需要获取目标文件的名称、不需要拼接全路径,可以直接调用getattrlist读取文件元数据中的名称字段,性能比realpath更高,额外开销极小。如果需要保留相对路径结构,也可以用该方案逐个获取路径段的实际大小写。
代码示例
#include <sys/attr.h> #include <stdint.h> #include <stdlib.h> #include <string.h> char* get_actual_filename_case(const char* path) { struct attrlist attr_list; memset(&attr_list, 0, sizeof(attr_list)); // 请求获取通用属性中的文件名称 attr_list.commonattr = ATTR_CMN_NAME; // 定义返回缓冲区,适配macOS最大255字节的文件名限制 struct { uint32_t len; char name[256]; } attr_buf; if (getattrlist(path, &attr_list, &attr_buf, sizeof(attr_buf), 0) == 0) { return strdup(attr_buf.name); } return NULL; }
Qt项目适配方案
如果使用Qt开发,可以直接将上述原生接口和QString做转换即可,不需要使用Qt的QDir遍历接口:
#include <QString> #include <sys/attr.h> #include <string.h> QString getActualFileNameCase(const QString& path) { QByteArray utf8Path = path.toUtf8(); struct attrlist attr_list; memset(&attr_list, 0, sizeof(attr_list)); attr_list.commonattr = ATTR_CMN_NAME; struct { uint32_t len; char name[256]; } attr_buf; if (getattrlist(utf8Path.constData(), &attr_list, &attr_buf, sizeof(attr_buf), 0) == 0) { return QString::fromUtf8(attr_buf.name); } return path; // 调用失败返回原路径兜底 }
方案说明
上述所有方案均不需要遍历父目录的所有条目,直接从文件系统的元数据中读取对应信息,性能比目录遍历方案高10~100倍(取决于父目录的文件数量),完全满足高性能场景的需求。
注意:调用前建议先确认输入路径对应的文件/目录确实存在,避免不必要的调用失败。
内容的提问来源于stack exchange,提问作者HiFile.app - best file manager
相关产品推荐
相关产品推荐

