如何确保目录对象的读取索引在 FATFS 中倒带?
How do I ensure that the read index of the directory object is rewound in FATFS?
我猜这是一个基本问题:我在 FatFs 中使用 f_readdir 函数从命令行读取目录的内容,但我遇到了问题多次将函数设置为 运行。第一次运行时它运行良好:我在 CLI 中键入 "directory",它会及时显示目录中的每个文件。然而,要求它再次重复 f_readdir 操作(即在第一个命令成功完成后再次输入 "directory" 命令)没有任何输出。
我相信这是因为文件读取对象在 f_readdir 操作结束时没有倒回到零,并且后续读取目录的请求是从索引的一部分开始的'存在。至少这是我目前能看到的最好的解释。它在 Elm Chan 的 FatFs website 上说 "When all directory items have been read and no item to read, a null string is stored into the fno->fname[] without any error. When a null pointer is given to the fno, the read index of the directory object is rewinded."
这是我的代码。忽略函数参数,它们是 运行 命令的 RTOS 内容:
void Cmd_directory::run(XString param, XRTOS::XCLI::userIO* io){
DIR dj; /*[IN] Directory search object */
FILINFO fno; /*[OUT] File information structure */
FRESULT res;
res = f_opendir(&dj, "0:");
while (res == FR_OK && fno.fname[0]) {
res = f_readdir(&dj, &fno);
io->print((const char*)fno.fname);
io->print("\r\n");
}
f_closedir(&dj);
}
这个while循环是我在网上找到的,所以不幸的是我没有完全理解fname索引是如何工作的,因为我已经阅读了很多次详细的解释。也许它没有意识到它正在根据我的 while 循环的条件到达目录的末尾,尽管它肯定会成功完成并关闭目录。当我再次 运行 函数时,我可以看到 fno 对象中仍然保存着上次循环中存储的文件信息。
我尝试过的事情(在这一点上值得补充我对编程世界还很陌生):
&fno = nullptr; //produces "error: lvalue required as left operand of assignment"
FILINFO *p = nullptr; //produces all sorts of errors
fno = p;
//these were shots in the dark
fno.fname[0] = 0;
memset(fno.fname, 0, sizeof(fno.fname));
我想这是一些我无法理解的基本内容,但如果我离题太远,请原谅我。不幸的是,我无法接触到真正的程序员 IRL,所以我不得不对社区进行投票。
哦,对了,我正在使用 Eclipse IDE、GNU ARM 构建工具和 STM32L。
此处:
while (res == FR_OK && fno.fname[0]) {
fno.fname[0]
是单元化的——你第一次很幸运,因为它包含非零垃圾。第二次它可能包含之前留在其中的任何函数 - 即上次调用的 NUL - 立即终止循环。
以下应该有效:
res = f_readdir( &dj, &fno ) ;
while( res == FR_OK && fno.fname[0] )
{
io->print((const char*)fno.fname);
io->print("\r\n");
res = f_readdir(&dj, &fno);
}
根据您之前的尝试,fno.fname[0] = 0;
很接近,如果您没有明确设置循环终止值的话!对您的代码进行以下小改动也应该有效:
fno.fname[0] = 1;
while (res == FR_OK && fno.fname[0]) {
res = f_readdir(&dj, &fno);
io->print((const char*)fno.fname);
io->print("\r\n");
}
但如果目录为空,它会打印一个空行。
老实说,ELM FatFs f_readdir()
的语义有些奇怪。你可能会考虑一个包装器来给它一个更一致和传统的接口:
FRESULT readdir( DIR* dp, /* [IN] Directory object */
FILINFO* fno /* [OUT] File information structure */ )
{
FRESULT res = f_readdir( dp, fno ) ;
if( res == FR_OK && fno->fname[0] == 0 )
{
res = FR_NO_FILE ;
}
return res ;
}
然后可以这样写(比如):
while( readdir( &dj, &fno ) == FR_OK )
{
io->print((const char*)fno.fname);
io->print("\r\n");
}
我猜这是一个基本问题:我在 FatFs 中使用 f_readdir 函数从命令行读取目录的内容,但我遇到了问题多次将函数设置为 运行。第一次运行时它运行良好:我在 CLI 中键入 "directory",它会及时显示目录中的每个文件。然而,要求它再次重复 f_readdir 操作(即在第一个命令成功完成后再次输入 "directory" 命令)没有任何输出。
我相信这是因为文件读取对象在 f_readdir 操作结束时没有倒回到零,并且后续读取目录的请求是从索引的一部分开始的'存在。至少这是我目前能看到的最好的解释。它在 Elm Chan 的 FatFs website 上说 "When all directory items have been read and no item to read, a null string is stored into the fno->fname[] without any error. When a null pointer is given to the fno, the read index of the directory object is rewinded."
这是我的代码。忽略函数参数,它们是 运行 命令的 RTOS 内容:
void Cmd_directory::run(XString param, XRTOS::XCLI::userIO* io){
DIR dj; /*[IN] Directory search object */
FILINFO fno; /*[OUT] File information structure */
FRESULT res;
res = f_opendir(&dj, "0:");
while (res == FR_OK && fno.fname[0]) {
res = f_readdir(&dj, &fno);
io->print((const char*)fno.fname);
io->print("\r\n");
}
f_closedir(&dj);
}
这个while循环是我在网上找到的,所以不幸的是我没有完全理解fname索引是如何工作的,因为我已经阅读了很多次详细的解释。也许它没有意识到它正在根据我的 while 循环的条件到达目录的末尾,尽管它肯定会成功完成并关闭目录。当我再次 运行 函数时,我可以看到 fno 对象中仍然保存着上次循环中存储的文件信息。
我尝试过的事情(在这一点上值得补充我对编程世界还很陌生):
&fno = nullptr; //produces "error: lvalue required as left operand of assignment"
FILINFO *p = nullptr; //produces all sorts of errors
fno = p;
//these were shots in the dark
fno.fname[0] = 0;
memset(fno.fname, 0, sizeof(fno.fname));
我想这是一些我无法理解的基本内容,但如果我离题太远,请原谅我。不幸的是,我无法接触到真正的程序员 IRL,所以我不得不对社区进行投票。
哦,对了,我正在使用 Eclipse IDE、GNU ARM 构建工具和 STM32L。
此处:
while (res == FR_OK && fno.fname[0]) {
fno.fname[0]
是单元化的——你第一次很幸运,因为它包含非零垃圾。第二次它可能包含之前留在其中的任何函数 - 即上次调用的 NUL - 立即终止循环。
以下应该有效:
res = f_readdir( &dj, &fno ) ;
while( res == FR_OK && fno.fname[0] )
{
io->print((const char*)fno.fname);
io->print("\r\n");
res = f_readdir(&dj, &fno);
}
根据您之前的尝试,fno.fname[0] = 0;
很接近,如果您没有明确设置循环终止值的话!对您的代码进行以下小改动也应该有效:
fno.fname[0] = 1;
while (res == FR_OK && fno.fname[0]) {
res = f_readdir(&dj, &fno);
io->print((const char*)fno.fname);
io->print("\r\n");
}
但如果目录为空,它会打印一个空行。
老实说,ELM FatFs f_readdir()
的语义有些奇怪。你可能会考虑一个包装器来给它一个更一致和传统的接口:
FRESULT readdir( DIR* dp, /* [IN] Directory object */
FILINFO* fno /* [OUT] File information structure */ )
{
FRESULT res = f_readdir( dp, fno ) ;
if( res == FR_OK && fno->fname[0] == 0 )
{
res = FR_NO_FILE ;
}
return res ;
}
然后可以这样写(比如):
while( readdir( &dj, &fno ) == FR_OK )
{
io->print((const char*)fno.fname);
io->print("\r\n");
}