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 中定义,命名的宏如下所示。当_USE_LFN 宏为0时不使能长文件名,具体各个宏值得定义在注释中解释。
#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 使用示例
代码中展示了 f_readdir 的使用示例,代码中使能了长文件名,通过判断 f_readdir 的返回值,并判断 fname[0] 是否为空来判断时候读到了目录的尾部,并对文件夹中的文件个数进行统计,用变量count表示。详细的示例如下:
/*
* 功 能: 扫描并打印文件夹中所有文件的名字,包括短文件名和长文件名
* 并记录文件夹中文件的个数(注:文件夹和隐藏文件不处理)
* 参数1: 文件夹的路径 例如 "0:/setting"
* 参数2: 记录文件个数的指针
*/
void cal_file_count_of_dir(uint8_t *dir_path, uint16_t *file_count)
{
uint16_t count = 0;
FRESULT ret; // 文件操作结果
FATFS fs; // FatFs文件系统对象
DIR dp;
FIL fp;
FILINFO Fileinfo;
#if _USE_LFN
TCHAR lfn[_MAX_LFN];
Fileinfo.lfname = lfn;
Fileinfo.lfsize = sizeof(lfn);
#endif
ret = f_opendir(&dp, dir_path);
if (ret == FR_NO_PATH) // 没有该文件夹
{
printf("没有 %s\n", dir_path);
while(1);
}
else if (ret != FR_OK)
{
printf("打开 %s 失败\n", dir_path);
}
else // 打开成功
{
while(1)
{
ret = f_readdir(&dp, &Fileinfo);
if(ret != FR_OK || Fileinfo.fname[0]==0 )
{
break; // 读取失败或者读取完所有条目
}
else if (Fileinfo.fname[0] == '.') // 隐藏文件
{
continue;
}
else if(Fileinfo.fattrib & AM_DIR) // 是文件夹
{
printf("Directory\n");
continue; // 文件夹不处理,继续读下一个
}
else
{
if(Fileinfo.lfname[0] == 0) // 先判断长文件名,要是先判断短文件名会出错,不知道为啥
{
if (Fileinfo.fname[0] != 0)
{
count++;
printf("%s\n", Fileinfo.fname); // 打印短文件名
}
}
else
{
count++; // 记录文件的个数
printf("%s\n", Fileinfo.lfname); // 打印长文件名
}
}
}
}
*file_count = count;
f_closedir(&dp); // 打开之后要关闭文件夹
}