FatFS: f_findfirst returns 与找到的文件不对应的字符串

FatFS: f_findfirst returns a string that does not correspond to the file found

我正在使用 FatFs 库在 SD 卡上创建和管理文件系统。目标是识别包含固件的文件,供引导加载程序更新(或不更新)设备。

我遵循的程序如下:

DIR  directory;
FILINFO filinfo;

f_findfirst(&directory, &filinfo, "", "firmware_");

据我了解,第一个以 "firmware_" 开头的文件应该被识别,信息存储在 filinfo 中。这确实有效,但是当我尝试从 filinfo.fname 中提取名称时,提取的名称如下:"[=17=]IRMWA~1.BIN".

我不知道为什么文件的命名是用这种格式提取的。想法是稍后获取文件的第二部分:“firmware_01_01_01”并执行 char 到 int 的转换以处理版本号,但我无法提取文件名的完整字符串。

  1. 始终阅读文档。

Description

After the directory specified by path could be opened, it starts to search the directory for items with the name specified by pattern. If the first item is found, the information about the object is stored into the file information structure fno.

The matching pattern can contain wildcard characters (? and *). A ? matches an any character and an * matches an any string in length of zero or longer. When support of long file name is enabled, only fname[] is tested at FF_USE_FIND == 1 and also altname[] is tested at FF_USE_FIND == 2. In this revision, there are some differences listed below between FatFs and standard systems in matching condition.

- "*.*" never matches any name without extension while it matches any name with or without extension at the standard systems.
- Any pattern terminated with a period never matches any name while it matches the name without extensiton at the standard systems.
- DBCS extended characters are compared in case-sensitive at LFN with ANSI/OEM API.

>

快捷信息

This is a wrapper function of f_opendir and f_readdir function. Available when FF_USE_FIND >= 1 and FF_FS_MINIMIZE <= 1. Examples

/* Search a directory for objects and display it */

void find_image_file (void) {
    FRESULT fr;     /* Return value */
    DIR dj;         /* Directory search object */
    FILINFO fno;    /* File information */

    fr = f_findfirst(&dj, &fno, "", "dsc*.jpg");  /* Start to search for photo files */

    while (fr == FR_OK && fno.fname[0]) {         /* Repeat while an item is found */
        printf("%s\n", fno.fname);                /* Display the object name */
        fr = f_findnext(&dj, &fno);               /* Search for next item */
    }

    f_closedir(&dj); 
    } 
  1. 然后你就会知道你需要使用:
    • 通配符
    • 您需要检查函数 return 值
    • 如果文件名的第一个字符为零 - 这意味着找不到文件

我使用的是在 ffconf.h 文件(FatFs 附带的选项文件)中激活的长文件名 (LFN)。问题是我使用的是 filinfo.fname,它指的是 8.3 文件名结构(短命名方案)。

如果 LFN 被激活,FILINFO 结构中的字段 lfnamelfsize 将被激活。这两个字段是指向 char 数组的指针以及大小。这两个字段必须在使用它们之前进行初始化,如下所示:

static char lfn[_MAX_LFN + 1] 
//MAX_LFN is defined in ffconf.h and is 255, maximum value for LFN
filinfo.lfname = lfn;
filinfo.lfsize = sizeof lfn;
f_findfirst(&directory, &filinfo, "", "firmware_*.bin");
(...)

可以阅读也显示示例的文档here

When LFN feature is enabled, lfname and lfsize in the file information structure must be initialized with valid value prior to use the f_readdir function. The lfname is a pointer to the string buffer to return the long file name. The lfsize is the size of the string buffer in unit of TCHAR.

lfname 和 lfsize 对 f_findfirst 的作用与 f_readdir 的作用相同。

This is a wrapper function of f_opendir and f_readdir

我遇到了类似的问题。这是我的代码。希望对您有所帮助

#define FW_FOLDER               "fw"
#define FW_PATH                 "0:/" FW_FOLDER
#define FW_BIN                  "*.bin"

FRESULT res;
DIR dir;
FILINFO fno;
static char fw_path[128];

// Find first item
res = f_findfirst(&dir, &fno, FW_PATH, FW_BIN);

// Create directory (optional)
if (res == FR_NO_PATH)
{
    printf("Creating %s directory!\n", FW_FOLDER);
    f_mkdir(FW_FOLDER);
}

// Repeat until proper item is found
while (res == FR_OK)
{
    // Make sure file name is valid
    if (fno.fname[0] == 0)
        break;
    
    // Debugging
    printf("Scanning: %s\n", fno.fname);

    // Make sure it is not a directory
    if (!(fno.fattrib & AM_DIR))
    {            
        // Success!
        printf("Found: %s\n", fno.fname);
        
        // Construct file path
        sprintf(fw_path, "%s/%s", FW_PATH, fno.fname);
        
        break;
    }
    
    // Move to the next one
    res = f_findnext(&dir, &fno);
}

// Close directory
f_closedir(&dir);

是的,您需要在 fatfs 库中启用 FF_USE_FIND == 1。如果您决定将 2 用于 FF_USE_FIND,则必须检查 altname 作为 fno 的一部分。

此外,我最终不得不将文件验证更新为这个片段

// Make sure file name is alpha numeric
if (!isalnum(fat_fno.fname[0]))
    break;