fat短文件名文件创建
FAT目录分为长文件名目录(LFN)以及短文件名目录(SFN),长文件目录是在短文件名目录上的一个扩展,具体采用长文件名还是短文件名由读取FAT文件系统的操作系统决定,蓝讯SDK是采用短文件名.
短文件名要遵循8.3格式,即8 字节的主文件名 + 3字节的扩展名
目录条目结构如下:
| 字段名 | 偏移 | 大小 | 说明 | 实例 |
|---|---|---|---|---|
| DIR_Name | 0 | 11 | 短文件名 | MIC001.WAV |
| DIR_Name_char | 0 | 8 | 短文件名字符部分 | MIC001空格空格(0x4D 0x49 0x43 0x30 0x30 0x31 0x20 0x20) |
| DIR_Name_suffix | 8 | 3 | 短文件名字符部分 | WAV(0x57 0x41 0x56) |
创建短文件名的函数是
FRESULTfs_open(constchar*path,u8 mode);//按路径打开或创建文件(短文件名创建文件)将文件名写入到磁盘的核心函数是dir_register(DIR *dp,const char *lfn);
具体流程为通过函数dir_alloc(dp,1)在目录中分配一项目录项空间,dp->dir[0]到dp->dir[7]放入短文件名,dp->dir[8]到dp->dir[10]放入文件名后缀.
设置短文件名的实例如下,
先声明默认的短文件名字符数组,存储默认文件名.
将文件名数组作为fs_open的参数
创建文件过程中调用的核心函数如下
constcharfile_name_mic[]="MIC00001.WAV";//文件名字符长度最大为8,后缀名为3charfname_buf[100];//存储文件路径memset(fname_buf,0,sizeof(fname_buf));fname_buf[0]='/';strcpy((char*)&fname_buf[pos],file_name_mic);res=fs_open((constchar*)fname_buf,FA_WRITE|FA_CREATE_NEW);res=pf_open(fname_buf,0,&fat_file,mode);res=follow_path(&dj,&fat_file,0,fname_buf)//走到目标路径,存储文件名.res=create_name(&dj,&(&fname_buf[1]));//把短文件名字符部分与短文件名后缀部分存入dp->fn中res=dir_register(&dj,0);//将文件名写入磁盘.res=dir_alloc(&dp,1);//为目录中分配一项目录项空间res=dir_next(dp,1);dj->dir=fs->win+(i%16)*32;//dp->dir用的数组空间是与磁盘交互读写的fs->win数组memcpy(dp->dir+0,dp->fn,11);//把dp->fn中的短文件名放入dp->dir中,dp->dir是最终放短文件名的数组.fat长文件名文件创建
创建一个有长文件名的文件,一定要有短文名,二者的文件名字符部分不需要有关联,文件系统判断文件是否存在,是通过短文件名,新创建的长文件名可以与已经存在的文件的长文件名重复,但新创建的文件的短文件名与已经存在的文件的短文件名不能重复.
长目录条目结构如下:
创建长文件名的函数是
FRESULTfs_open_lfn(constchar*path,constchar*lfn,u8 mode);//按路径打开或创建文件(长文件名创建文件)一个目录项空间为32字节,能存储13个字符,SDK中的程序设置最多有ENTRY_NUM=8个目录项空间,一共能存储104个字符.包括文件名字符部分,后缀名与点.一个目录项存够13个字符后,下一个目录项继续存之后的字符的13个字符,直到存完所有字符.
设置长文件的方法如下.
先声明默认的短文件名字符数组,存储默认文件名.
声明存储长文件名的数组,存储长文件名.如果不包含中文的话,长文件名格式为:文件名的长度x,0,字符1,0,字符2,0,…字符x,0.
lfn_buf[0]存储文件长度,lfn_buf[1]=0,lfn_buf[2]开始存储长文件名,一个字符占两个字节.
将短文件名数组与长文件名数组作为fs_open_lfn的参数
磁盘存储长文件名需要多个目录项空间
在创建文件的过程中,通过函数dir_alloc(dp,entries);在目录中分配连续的目录项空间
constcharfile_name_mic[]="MIC00001.WAV";//文件名字符长度最大为8,后缀名为3charfname_buf[100];//存储文件路径memset(fname_buf,0,sizeof(fname_buf));fname_buf[0]='/';charlfn_buf[100];//存储长文件create_timestamp_filename(lfn_buf);//生成长文件名strcpy((char*)&fname_buf[pos],file_name_mic);//生成短文件名res=fs_open_lfn((constchar*)fname_buf,(constchar*)lfn_buf,FA_WRITE|FA_CREATE_NEW);res=pf_open(fname_buf,lfn_buf,&fat_file,mode);res=follow_path(&dj,&fat_file,lfn_buf,fname_buf)res=create_name(&dj,&(&fname_buf[1]));//把短文件名字符部分与短文件名后缀部分存入dp->fn中res=dir_register(&dj,lfn_buf);//将长文件名与短文件名写入磁盘.res=dir_alloc(&dp,entries);//在目录中分配连续的目录项空间memcpy(dirbuf,&lfn[2],len);//复制长文件名内容ST_WORD(dirbuf+len,0);//末尾设置0,标志文件结束memcpy(&dp->dir[0x01],&dirbuf[0+pos],10);//将长文件名复制到dp->dir中.创建长文件的实例条目结构如下
长文件名为001_ABCD_20260123_040513_32F.WAV
长文件名数组的值为:32 0 0x30 0 0x30 0 0x31 0 0x5f 0 0x41 0 0x42 0 0x43 0 0x44 0 0x5f 0 0x32 0 0x30 0 0x32 0 0x36 0 0x30 0 0x31 0 0x32 0 0x33 0 0x5f 0 0x30 0 0x34 0 0x30 0 0x35 0 0x31 0 0x33 0 0x5f 0 0x33 0 0x32 0 0x46 0 0x2e 0 0x57 0 0x41 0 0x56 0 0 0
| 位置 | 字段名 | 偏移 | 大小 | 说明 | 实例中的值 |
|---|---|---|---|---|---|
| 第一块 | DIR_Name | 0 | 1 | 序号(1-20),用来表示此条目属于长文件名序列条目中的第几条.且长文件名序列首条条目的值应&0x40以进行标识 SDK中程序设置的序号最大为ENTRY_NUM=8 | 0x41 |
| 第一块 | DIR_Name1 | 1 | 10 | 长文件名,第1~第5字符(此处需要用Unicode编码,一个字符占两个字节) | 001_A (0x30 0 0x30 0 0x31 0 0x5f 0 0x41 0) |
| 第一块 | DIR_Attr | 11 | 1 | 长文件名属性,此值永远为ATTR_LONG_NAME 0x0F | 0x0f |
| 第一块 | DIR_type | 12 | 1 | 类型,必须为0 | 0 |
| 第一块 | DIR_chksum | 13 | 1 | 和校验,根据短文件名计算和校验 | chknum |
| 第一块 | DIR_Name2 | 14 | 12 | 长文件名,第6~第11字符(此处需要用Unicode编码,一个字符占两个字节) | BCD_20 (0x42 0 0x43 0 0x44 0 0x5f 0 0x32 0 0x30 0) |
| 第一块 | DIR_fstcluslo | 26 | 2 | 必须为0 | 0 |
| 第一块 | DIR_Name3 | 28 | 4 | 长文件名,第12~第13字符(此处需要用Unicode编码,一个字符占两个字节) | 26 (0x32 0 0x36 0) |
| 第二块 | DIR_Name | 0 | 1 | 序号,长文件名序列条目中的第几条 | 0x2 |
| 第二块 | DIR_Name1 | 1 | 10 | 长文件名,第1~第5字符(此处需要用Unicode编码,一个字符占两个字节) | 0123_ (0x30 0 0x31 0 0x32 0 0x33 0 0x5f 0) |
| 第二块 | DIR_Attr | 11 | 1 | 长文件名属性,此值永远为ATTR_LONG_NAME 0x0F | 0x0f |
| 第二块 | DIR_type | 12 | 1 | 类型,必须为0 | 0 |
| 第二块 | DIR_chksum | 13 | 1 | 和校验,根据短文件名计算和校验 | chknum |
| 第二块 | DIR_Name2 | 14 | 12 | 长文件名,第6~第11字符(此处需要用Unicode编码,一个字符占两个字节) | 040513 (0x30 0 0x34 0 0x30 0 0x35 0 0x31 0 0x33 0) |
| 第二块 | DIR_fstcluslo | 26 | 2 | 必须为0 | 0 |
| 第二块 | DIR_Name3 | 28 | 4 | 长文件名,第12~第13字符(此处需要用Unicode编码,一个字符占两个字节) | _3 (0x5f 0 0x33 0) |
| 第三块 | DIR_Name | 0 | 1 | 序号,长文件名序列条目中的第几条 | 0x3 |
| 第三块 | DIR_Name1 | 1 | 10 | 长文件名,第1~第5字符(此处需要用Unicode编码,一个字符占两个字节) | 2F.WA (0x32 0 0x46 0 0x2e 0 0x57 0 0x41 0) |
| 第三块 | DIR_Attr | 11 | 1 | 长文件名属性,此值永远为ATTR_LONG_NAME 0x0F | 0x0f |
| 第三块 | DIR_type | 12 | 1 | 类型,必须为0 | 0 |
| 第三块 | DIR_chksum | 13 | 1 | 和校验,根据短文件名计算和校验 | chknum |
| 第三块 | DIR_Name2 | 14 | 12 | 长文件名,第6~第11字符(此处需要用Unicode编码,一个字符占两个字节) | V文件结束标志 (0x56 0 0 0) |
| 第三块 | DIR_fstcluslo | 26 | 2 | 必须为0 | 0 |
| 第三块 | DIR_Name3 | 28 | 4 | 长文件名,第12~第13字符(此处需要用Unicode编码,一个字符占两个字节) | 无内容 (0xff 0xff 0xff 0xff) |
exfat文件名详见解析
exFAT 文件系统原理详解