FATFS中如何用f_readdir获取的fname变量作为f_open的文件名?
FATFS中f_readdir读取文件名后f_open返回FR_NOFILE的解决方案
问题根源
f_readdir返回的sdfileinfo.fname仅包含纯文件名(如t123.txt),不包含所在目录的路径。你当前的工作目录是挂载后的根目录0:/,直接将纯文件名传入f_open时,函数会去根目录查找该文件,而非0:/test目录,因此返回FR_NOFILE错误。
解决方案
方案1:切换工作目录到目标目录
在打开目录前,先切换工作目录到0:/test,之后f_open会默认在当前工作目录下查找文件:
// 挂载文件系统 f_mount(&SDFatFS, "0:", 1); // 切换工作目录到0:/test f_chdir("0:/test"); // 打开当前工作目录(也可直接写"./") f_opendir(&mydir, "."); // 读取目录项 while(f_readdir(&mydir, &sdfileinfo) == FR_OK && sdfileinfo.fname[0]){ // 过滤.和..目录项 if(strcmp(sdfileinfo.fname, ".") != 0 && strcmp(sdfileinfo.fname, "..") != 0){ // 直接用纯文件名打开,此时工作目录是0:/test if(f_open(&SDFile, sdfileinfo.fname, FA_READ | FA_OPEN_EXISTING) == FR_OK){ // 处理文件逻辑 f_close(&SDFile); } } }
方案2:手动拼接完整路径
将目录路径与f_readdir返回的文件名拼接成完整路径,再传入f_open:
// 挂载文件系统 f_mount(&SDFatFS, "0:", 1); // 打开0:/test目录 f_opendir(&mydir, "0:/test"); // 定义足够大小的路径缓冲区 char full_path[64]; // 读取目录项 while(f_readdir(&mydir, &sdfileinfo) == FR_OK && sdfileinfo.fname[0]){ // 过滤.和..目录项 if(strcmp(sdfileinfo.fname, ".") != 0 && strcmp(sdfileinfo.fname, "..") != 0){ // 拼接完整路径 sprintf(full_path, "0:/test/%s", sdfileinfo.fname); // 用完整路径打开文件 if(f_open(&SDFile, full_path, FA_READ | FA_OPEN_EXISTING) == FR_OK){ // 处理文件逻辑 f_close(&SDFile); } } }
注意事项
- 拼接路径时,要确保缓冲区大小足够,避免字符串溢出;若路径较长,可适当增大缓冲区(如
char full_path[256];,FATFS最大路径长度通常为255字符)。 - 必须过滤
f_readdir返回的.(当前目录)和..(上级目录)项,否则尝试打开这两个项会导致错误。
内容的提问来源于stack exchange,提问作者N N
相关产品推荐
相关产品推荐

