1. 函数原型
函数原型: FRESULT f_readdir (DIR* dp, FILINFO* fno)
@param1 : 打开的目录对象结构体指针
@param2 : 存储在读条目中的文件信息结构指针
@return : typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
函数描述: f_readdir 在 f_opendir之后使用,按顺序读取目录条目。反复调用该函数可以读取目录中的所有条目。当已经读取完所有条目并且没有其他条目可读时函数返回一个空的字符串到 f_name[] 中,并且不返回错误提示。当FileInfo指向一个空指针,读取的目录对象将被倒回。
当LFN打开时,文件信息结构体中的 lfname 和 lfsize 必须在使用 f_readdir 函数前初始化为有效值。lfname 是一个返回长文件名的字符串缓冲区指针;lfsize 表示以 TCHAR 为单位的字符串缓冲区大小。如果读缓冲区或者LFN工作缓冲区容量不够存储LFN或者对象没有LFN,将返回一个空字符串到LFN读缓冲区。在没有对 Unicode API 配置的情况下,如果LFN包含任何不能转换成OEM码的字符,将返回一个空字符串。当 lfname 是 NULL 时,LFN 没有任何返回。当对象没有 LFN 时,一些小写字母被包含到 SFN 中。
当相关的路径特征被使能(_FS_RPATH==1),".“和”…"不被过滤并将出现在所读条目中。当_FS_MINIMIZE<=1时,此函数可用。
2. 长文件名
长文件名的使能在 ffconf.h 中定义,命名的宏如下所示
#define _USE_LFN 2
#define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature.
/
/ 0: Disable LFN feature. _MAX_LFN has no effect. // 禁用LFN功能。_MAX_LFN无效
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. // 在BSS上使用静态工作缓冲区启用LFN。 始终不是线程安全的
/ 2: Enable LFN with dynamic working buffer on the STACK. // 在堆栈上通过动态工作缓冲区启用LFN
/ 3: Enable LFN with dynamic working buffer on the HEAP. // 在HEAP上启用具有动态工作缓冲区的LFN
/
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must
/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
3. f_readdir 使用示例
使用示例:
int scan_files(void)
{
#if _USE_LFN
TCHAR lfn[_MAX_LFN];
Fileinfo.lfname = lfn;
Fileinfo.lfsize = sizeof(lfn);
#endif
uint8_t ret;
uint8_t count = 0;
Dir Dir; // 文件夹
TCHAR *DIR_PATH[] = "0:/test";
FILINFO Fileinfo;
if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK) // 挂载SD卡
{
printf("SD卡挂载失败\n");
return -1;
}
else // 挂载SD卡成功
{
if(f_opendir(&Dir,(const TCHAR *)DIR_PATH) != FR_OK) // 打开目录失败
{
printf("打开目录失败 ret = %d\n", ret);
return -1;
}
else // 成功打开目录
{
while(1)
{
ret = f_readdir(&Dir, &Fileinfo);
if(ret != FR_OK || Fileinfo.fname[0] == 0)
{
break; // 读取失败或者读取完所有条目
}
else if (Fileinfo.fname[0] == '.' || strcpy(Fileinfo.fname[0], ".." == 0)) // 隐藏文件
{
continue;
}
else
{
if(Fileinfo.lfname[0] == 0)
{
printf("lfname : error\n");
}
else
{
count++; // 记录文件的个数
printf("%s\n", Fileinfo.lfname); // 打印文件名
}
}
if(Fileinfo.fattrib & AM_DIR) // 是文件夹
{
printf("Directory\n");
}
}
f_close(&Dir);
}
}
printf("count = %d\n", count);
}