7.10. FS
Overview
提供文件系统接口应用示例、常用相关 API 介绍和常见问题。
7.10.1. 应用示例
示例演示: 通过挂载SD卡进行文件系统接口调用:
长文件名和短文件名的打开
长文件名和短文件名的目录创建
fscan、fslect和fget_name的用法
example: 进入 apps/demo/demo_DevKitBoard/include/demo_config.h
,开启宏 USE_FS_TEST_DEMO
。
Note
1.app_config.h:使能SD卡,需要定义#define TCFG_SD0_ENABLE 1同时在例子的main1.c中有以下几个宏 //测试例选择
#define FILENAME_TEST 0 //长短文件名打开和目录创建操作测试
#define FS_FSCAN_TEST 1 //扫描文件测试 fscan和fselect使用
2.长文件名:通过open的”w+”打开可 读/写文件,若文件存在则原文件会被直接覆盖;若文件不存在则创建该文件。通过fopen的”r”以只读方式打开文件,该文件必须存在。
3.短文件名文件除了通过像长文件名的方式进行创建和打开读写之外,也可以直接通过路径+短文件名如CONFIG_ROOT_PATH”filename.txt”,使用8+3规则,短文件名不能超过8个字节。
4.在测试创建长文件夹名和长文件名目录时,将filename_test()中的file_name修改如下:
char file_name[128] = { '/','\\','U',0x4B,0x6D,0xD5,0x8B,0x7F,0x95,0x87,0x65,0xF6,0x4E,0x39,0x59,0x0D,0x54,0x4B,0x6D,0xD5,0x8B,'/',0x00,'\\','U',0x4B,0x6D,0xD5,0x8B,0x1B,0x52,0xFA,0x5E,0x7F,0x95,0x87,0x65,0xF6,0x4E,0x0D,0x54,0x4B,0x6D,0xD5,0x8B,0x2E,0x00,0x74,0x00,0x78,0x00,0x74,0x00 };
注意在文件夹名后’/’,0x00,’\’,’U’中间写入0x00,否则会创建目录失败。
5.fscan():test中使用fscan()扫描CONFIG_STORAGE_PATH”/C/”路径中,搜索.txt格式文件-tTXT,包括子目录-r,按照按照文件号排序-sn
6.fslect():test中通过使用fselect()通过选择的按顺序、按簇号和序号选择文件,然后通过fget_name()获取文件名。
7.fget_name():传入的buf长度若少于16个字节则获取短文件名,大于等于16个字节则获取长文件名,由小机filename_test()若按照unicode编码创建的文件名读取到文件名均为unicode编码(包括中英文);由windows创建的短英文文件名读取到文件名为utf-8编码,短中文文件名和长中英文文件名读取文件名均为unicode编码。
8.注意使用fget_name以后使用put_buf将文件名打印,不可使用printf(遇到0会结束打印),打印的文件名为对应的fget_name获取到的编码格式的编码。
7.10.2. 常见问题
SD卡打开文件失败?
答:确保SD卡已经挂载成功后才能调用文件系统接口。
有些SD卡能挂载成功,有些却挂载不了?
答:不同类型的SD卡读写速率不一样,对于低速卡如果挂载不成功时,尝试调整对应的板级配置
7.10.3. API Reference
Seek orig for fseek function
-
SEEK_SET
Seek from beginning of file.
-
SEEK_CUR
Seek from current position.
-
SEEK_END
Seek from end of file.
File attributes bits for fset_attr and fget_attr funciton
-
F_ATTR_RO
只读
-
F_ATTR_ARC
文件
-
F_ATTR_DIR
目录
-
F_ATTR_VOL
卷标
-
FSELECT_MODE
Select mode for fselect function
-
FSEL_FIRST_FILE
选择第一个文件
-
FSEL_LAST_FILE
选择最后一个文件
-
FSEL_NEXT_FILE
选择下一个文件
-
FSEL_PREV_FILE
选择上一个文件
-
FSEL_CURR_FILE
选择当前文件
-
FSEL_BY_NUMBER
根据文件序号选择
-
FSEL_BY_SCLUST
根据分配单元选择文件
-
FSEL_AUTO_FILE
自动选择文件
-
FSEL_NEXT_FOLDER_FILE
选择下一个文件夹的文件
-
FSEL_PREV_FOLDER_FILE
选择上一个文件夹的文件
-
FSEL_BY_PATH
根据文件路径选择
-
FCYCLE_MODE
Cycle mode for fselect function
-
FCYCLE_LIST
全部文件循环模式
-
FCYCLE_ALL
unused
-
FCYCLE_ONE
当前文件循环模式
-
FCYCLE_FOLDER
文件夹循环模式
-
FCYCLE_RANDOM
随机循环模式
-
FCYCLE_MAX
unused
-
enum [anonymous]
Values:
-
enumerator FS_IOCTL_GET_FILE_NUM
unused
-
enumerator FS_IOCTL_FILE_CHECK
unused
-
enumerator FS_IOCTL_GET_ERR_CODE
暂不支持
-
enumerator FS_IOCTL_FREE_CACHE
unused
-
enumerator FS_IOCTL_SET_NAME_FILTER
设置文件过滤
-
enumerator FS_IOCTL_GET_FOLDER_INFO
获取文件夹序号和文件夹内文件数目
-
enumerator FS_IOCTL_SET_LFN_BUF
512
-
enumerator FS_IOCTL_SET_LDN_BUF
512
-
enumerator FS_IOCTL_SET_EXT_TYPE
设置后缀类型
-
enumerator FS_IOCTL_OPEN_DIR
打开目录
-
enumerator FS_IOCTL_ENTER_DIR
进入目录
-
enumerator FS_IOCTL_EXIT_DIR
退出目录
-
enumerator FS_IOCTL_GET_DIR_INFO
获取目录信息
-
enumerator FS_IOCTL_GETFILE_BYNAME_INDIR
由歌曲名称获得歌词
-
enumerator FS_IOCTL_GET_DISP_INFO
用于长文件名获取
-
enumerator FS_IOCTL_MK_DIR
创建文件夹
-
enumerator FS_IOCTL_GET_ENCFOLDER_INFO
获取录音文件信息
-
enumerator FS_IOCTL_GET_OUTFLASH_ADDR
获取外置flash实际物理地址(暂时用于手表case,特殊fat系统)
-
enumerator FS_IOCTL_FLUSH_WBUF
刷新wbuf
-
enumerator FS_IOCTL_SAVE_FAT_TABLE
seek加速处理
-
enumerator FS_IOCTL_INSERT_FILE
插入文件
-
enumerator FS_IOCTL_DIVISION_FILE
分割文件
-
enumerator FS_IOCTL_STORE_CLUST_RANG
存储CLUST_RANG 信息
-
enumerator FS_IOCTL_GET_FILE_NUM
-
struct imount *mount(const char *dev_name, const char *path, const char *fs_type, int cache_num, void *dev_arg)
挂载设备虚拟文件系统
- Parameters
dev_name – 设备名称
path – 挂载点路径
fs_type – 文件系统类型(支持”fat” “devfs” “ramfs” “sdfile”)
cache_num – 文件系统缓存
dev_arg – 设备参数指针
- Returns
指向挂载点结构体的指针
- Returns
NULL 挂载失败
-
int unmount(const char *path)
卸载设备虚拟文件系统
- Parameters
path – 挂载点路径
- Returns
0: 卸载成功
- Returns
other: 卸载失败
-
int f_format(const char *path, const char *fs_type, u32 clust_size)
格式化驱动器
- Parameters
path – 需要格式化的根目录
fs_type – 文件系统类型
clust_size – 簇大小,簇为0时默认为卡本身簇大小
- Returns
0: 格式化成功
- Returns
other: 格式化失败
-
int f_free_cache(const char *path)
刷新文件缓存数据(一般使用在fclose后某些数据还没有及时写进SD卡,需要主动刷新一下缓存区)
- Parameters
path – 需要刷新的根目录
- Returns
0: 刷新成功
- Returns
other: 刷新失败
-
FILE *fopen(const char *path, const char *mode)
打开文件, 获取指向文件流的文件指针
Note
fopen自动打开、创建文件夹和文件,打开模式只支持”r” “rb” “r+” “w” “w+”
设备路径+文件,其中文件传入格式:”music/test/1/2/3/pk*.wav” “JL_REC/AC69****.wav” “JL_REC/AC690000.wav”
文件名带*号,带多少个*表示多少个可变数字,最多为8+3的大小,如表示可变数字名称变为XXX0001,XXXX002这样得格式,不带*号则只创建一个文件,写覆盖。
文件名长度超过8个字节的需要用长文件名打开
- Parameters
path – 文件路径
mode – 打开模式
- Returns
指向文件流的文件指针
- Returns
NULL: 打开失败
-
int fread(void *buf, u32 size, u32 count, FILE *file)
从文件中读取数据
- Parameters
buf – [out] 保存读取到的数据
size – 每次读取字节数
count – 总共读取次数
file – 指向文件流的文件指针
- Returns
成功读取到的数据的字节长度
-
int fwrite(void *buf, u32 size, u32 count, FILE *file)
写入数据到文件中
- Parameters
buf – [in] 需要写入的数据
size – 每次写入字节数
count – 总共写入次数
file – 指向文件流的文件指针
- Returns
成功写入的数据的字节长度
-
int fseek(FILE *file, int offset, int orig)
设置文件指针的位置
- Parameters
file – 指向文件流的文件指针
offset – 偏移量
orig – 偏移的基准位置
- Returns
成功返回0
-
int fseek_fast(FILE *file, int offset, int orig)
快速设置文件指针的位置
Note
一般手表case使用,去除互斥,设置ram里面跑
- Parameters
file – 指向文件流的文件指针
offset – 偏移量
orig – 偏移的基准位置
- Returns
成功返回0
-
int fread_fast(void *buf, u32 size, u32 count, FILE *file)
从文件中快速读取数据
Note
一般手表case使用,去除互斥,设置ram里面跑
- Parameters
buf – [out] 保存读取到的数据
size – 每次读取字节数
count – 总共读取次数
file – 指向文件流的文件指针
- Returns
成功读取到的数据的字节长度
-
int fget_name(FILE *file, u8 *name, int len)
获取文件名(不包含目录)
- Parameters
file – 指向文件流的文件指针
name – 保存文件名的buffer
len – buffer的长度,大于15个字节获取的是长文件名,小于16个字节获取的是短文件名
- Returns
文件名的长度(大于0)
-
int frename(FILE *file, const char *fname)
重命名文件
- Parameters
file – 指向文件流的文件指针
path – 文件的新文件名,不需要加目录路径
- Returns
0: 成功
- Returns
other: 失败
-
int fdelete(FILE *file)
删除文件,操作成功后会自动关闭文件
- Parameters
file – 指向文件流的文件指针
- Returns
0: 删除成功
- Returns
other: 删除失败
-
int fdelete_by_name(const char *fname)
根据文件路径删除文件
- Parameters
fname – 文件路径
- Returns
0: 删除成功
- Returns
other: 删除失败
-
int fget_free_space(const char *path, u32 *space)
获取剩余空间
- Parameters
path – 设备路径
space – 保存剩余空间的大小
- Returns
0: 获取成功
- Returns
other: 获取失败
-
int fget_physical_total_space(const char *path, u32 *space)
获取存储设备的物理总空间(注意是物理大小,并不是分区的逻辑空间大小)
- Parameters
path – 根目录
space – 保存总空间的大小
- Returns
0: 获取成功
- Returns
other: 获取失败
-
int fget_path(FILE *file, struct vfscan *fscan, u8 *name, int len, u8 is_relative_path)
获取当前文件相对路径和绝对路径
- Parameters
file – 指向文件流的文件指针
fscan – 文件扫描结构体句柄
name – 保存文件路径的buffer
len – buffer的长度
is_relative_path – 是否要获取相对路径
- Returns
文件名的长度(大于0)
-
struct vfscan *fscan(const char *path, const char *arg, u8 max_deepth)
文件扫描
Note
arg扫描参数
-t 文件类型
-r 包含子目录
-d 扫描文件夹
-a 文件属性 r: 读, /: 非
-s 排序方式, t:按时间排序, n:按文件号排序
- Parameters
path – 扫描路径
arg – 扫描参数设置
max_deepth – 扫描目录层数,最大为9
- Returns
虚拟文件扫描结构体句柄
- Returns
NULL: 扫描失败
-
struct vfscan *fscan_interrupt(const char *path, const char *arg, u8 max_deepth, int (*callback)(void))
可打断的文件扫描
Note
arg扫描参数
-t 文件类型
-r 包含子目录
-d 扫描文件夹
-a 文件属性 r: 读, /: 非
-s 排序方式, t:按时间排序, n:按文件号排序
- Parameters
path – 扫描路径
arg – 扫描参数设置
max_deepth – 扫描目录层数,最大为9
callback – 每扫描完一个目录后回调一次
- Returns
虚拟文件扫描结构体句柄
- Returns
NULL: 扫描失败
-
struct vfscan *fscan_enterdir(struct vfscan *fs, const char *path)
文件扫描(进入指定子目录,只扫此目录下文件信息)
- Parameters
fs – 文件扫描结构体句柄
path – 指定目录的相对路径
- Returns
虚拟文件扫描结构体句柄
- Returns
NULL: 扫描失败
-
struct vfscan *fscan_exitdir(struct vfscan *fs)
返回上一层的文件扫描目录
- Parameters
fs – 文件扫描结构体句柄
- Returns
虚拟文件扫描结构体句柄
- Returns
NULL: 扫描失败
-
FILE *fselect(struct vfscan *fs, int selt_mode, int arg)
选择文件
- Parameters
fs – 文件扫描结构体句柄
selt_mode – 选择模式(支持按簇号、序号、路径选择)
arg – 选择参数,默认0
- Returns
指向文件流的文件指针
- Returns
NULL: 选择操作失败
-
int fdir_exist(const char *dir)
检查挂载点是否存在
- Parameters
dir – 挂载点路径
- Returns
1: 存在
- Returns
0: 不存在
-
int fget_attr(FILE *file, int *attr)
获取文件的文件属性
- Parameters
file – 指向文件流的文件指针
attr – 保存操作成功后文件的文件属性信息
- Returns
0: 获取成功
- Returns
other: 获取失败
-
int fset_attr(FILE *file, int attr)
设置文件的文件属性
- Parameters
file – 指向文件流的文件指针
attr – 文件属性码
- Returns
0: 设置成功
- Returns
other: 设置失败
-
int fget_attrs(FILE *file, struct vfs_attr *attr)
获取文件的详细信息如属性、簇号、大小等
- Parameters
file – 指向文件流的文件指针
attr – 保存操作成功后文件的详细信息
- Returns
0: 获取成功
- Returns
other: 获取失败
-
struct vfs_partition *fget_partition(const char *path)
获取路径对应的分区
- Parameters
path – 分区路径
- Returns
指向分区结构体的指针
- Returns
NULL: 获取失败
-
int fset_vol(const char *path, const char *name)
设置路径对应的卷标的名称
- Parameters
path – 卷标路径
name – 卷标名称
- Returns
0: 设置成功
- Returns
other: 设置失败
-
int fmove(FILE *file, const char *path_dst, FILE **newFile, int clr_attr, int path_len)
移动文件
- Parameters
file – 指向文件流的文件指针
path_dst – 目标路径,注意如果不需要更改原文件名,路径不需要填写文件名,如/aa/即可,根目录前面不能加分区路径
newFile – 保存操作成功后文件在新路径的文件流指针
clr_attr – 是否清除原有文件的文件属性
path_len – 目标路径长度
- Returns
0: 移动成功(自动关闭旧文件流)
- Returns
other: 移动失败
-
int fget_err_code(const char *path)
获取文件系统的错误代码
- Parameters
path – 文件路径
- Returns
文件错误码
-
int fname_to_path(char *result, const char *path, const char *fname, int len, u8 is_dir, u8 is_lfn)
拼接文件名(目录+文件名) (特别用于中文名文件的路径拼接)
- Parameters
result – 保存操作成功后的文件路径的字符串
path – 目录路径
fname – 文件名
len – fname的长度
is_dir – 拼接的是否为文件夹
is_dir – 拼接的是否为长文件名
- Returns
文件名的长度(大于0)
-
int fget_folder(struct vfscan *fs, struct ffolder *arg)
获取文件夹信息,获取文件夹序号和文件夹内文件数目
- Parameters
fs – vfscan 结构句柄
arg – 文件夹信息结构句柄
- Returns
0成功, 非0错误。
-
int fset_lfn_buf(struct vfscan *fs, void *arg)
设置长文件名Buf (现已不常用)
- Parameters
fs – vfscan 句柄
arg – buf
- Returns
0成功, 非0错误。
-
int fset_ldn_buf(struct vfscan *fs, void *arg)
设置长文件夹名Buf (现已不常用)
- Parameters
fs – vfscan 句柄
arg – buf
- Returns
0成功, 非0错误。
-
int fset_ext_type(const char *path, void *ext_type)
设置后缀名过滤(现已不常用)
- Parameters
path – 根路径
ext_type – 后缀名
- Returns
0成功, 非0错误。
-
int fopen_dir_info(const char *path, FILE **pp_file, void *dir_dj)
文件浏览使用,打开目录
- Parameters
path – 路径
pp_file – 文件句柄
dir_dj – 目录信息句柄
- Returns
无意义
-
int fenter_dir_info(FILE *file, void *dir_dj)
文件浏览使用,进入目录
- Parameters
file – 文件句柄
dir_dj – 目录信息句柄
- Returns
目录项总数
-
int fget_dir_info(FILE *file, u32 start_num, u32 total_num, void *buf_info)
文件浏览使用,获取目录信息
- Parameters
file – 文件句柄
start_num – 起始位置
total_num – 获取目录个数
buf_info – 目录信息句柄
- Returns
获取的目录数
-
int fstore_clust_rang(FILE *file)
存储文件簇信息
Note
一般手表case使用, 用于fget_fat_outflash_addr()之前调用,节省fget_fat_outflash_addr()时间
- Parameters
file – 文件句柄
- Returns
0成功, 非0错误。
-
int fget_fat_outflash_addr(FILE *file, char *name, void *buf_info, int buf_len)
获取外置flash实际物理地址
Note
一般手表case使用
- Parameters
file – 文件句柄
name – sdfile格式文件名
buf_info – 存储相关信息结构buf指针
buf_len – buf 长度
- Returns
0表示buf不够 大于 0 表示存储多少个信息结构,其他 错误
-
int fget_file_byname_indir(FILE *file, FILE **newFile, void *ext_name)
文件浏览使用,由歌曲名称获取歌词
- Parameters
file – 歌曲文件句柄
newFile – 歌词文件句柄
ext_name – 后缀名称
- Returns
0成功, 非0错误。
-
int fget_disp_info(FILE *file, void *arg)
获取长文件名和长文件夹名信息(现在不常使用)
Note
需要先设置长文件名或者长文件夹名buf进去
- Parameters
file – 歌曲文件句柄
arg – 长文件相关信息结构指针
- Returns
0成功, 非0错误。
-
int fmk_dir(const char *path, char *folder, u8 mode)
创建目录
- Parameters
path – 路径
folder – 文件夹名称,不需要 /
mode – 目录属性(1 设置为隐藏属性, 0 不设置 )
- Returns
0成功,非0不成功
-
int fget_encfolder_info(const char *path, char *folder, char *ext, u32 *last_num, u32 *total_num)
获取录音文件信息(现在不常用)
- Parameters
path – 路径
folder – 文件夹名称
ext – 文件名后缀
last_num – 可变数字最大数字
total_num – 文件总数
- Returns
0成功,非0不成功
-
const char *fname_after_root(const char *path)
截取path中根目录之后的文件名
- Parameters
path – 路径
- Returns
文件名
-
const char *fget_fs_type(const char *path)
获取文件系统类型
- Parameters
path – 路径
- Returns
文件系统类型
-
int fget_name_type(char *path, int len)
判断文件路径是否带有unicode编码
- Parameters
path – 路径
len – 路径长度
- Returns
是否带unicode
-
int get_last_num(void)
录音获取最后序号
- Returns
最后序号
-
void set_bp_info(u32 clust, u32 fsize, u32 *flag)
设置断点参数
Note
1.接口调用在扫描前 2.使用完需要put_bp_info对应释放buf
- Parameters
clust – 记录的簇号
fsize – 记录的文件大小
flag – 文件是否存在标志
-
void put_bp_info(void)
释放内存
-
void ff_set_FileInDir_enable(u8 enable)
优化扫盘速度,优化文件打开速度,如果不需要切换文件夹的操作,可置0关闭
Note
1.目的是是否去除获取文件夹内所有文件功能,默认enable 是1 获取数目,置0不获取,所以不需要切换文件夹操作的功能,可置0 关闭 2.在扫描前调用接口
- Parameters
enable – 开关
-
void ff_set_DirBaseInfo(void *buf, u16 n)
设置目录项基点信息(用于加速)
Note
1.加速序号选择文件,明显效果体现在上一曲加速 2.注意buf使用
- Parameters
buf – 存储基点buf (长度 10 * n)
n – 基点数目
-
void fat_set_datetime_info(u16 year, u8 month, u8 day, u8 hour, u8 minute, u8 second)
设置文件的创建时间
- Parameters
year – 年
month – 月
day – 日
hour – 小时
minute – 分钟
second – 秒
隐藏属性文件是否过滤
- Parameters
flag – 置1 为过滤
-
void fat_save_already_size_enable(char enable)
是否保存预申请长度
- Parameters
enable – 1保存,0 不保存
-
void fat_set_pre_create_chain_num(u16 num)
设置预申请簇数目
- Parameters
num – 数目(1-0x1fe)
-
int fsave_fat_table(FILE *file, u16 btr, u8 *buf)
存储文件簇信息
Note
seek加速,4字节对齐
- Parameters
file – 文件句柄
btr – buf 长度
buf – buf指针
- Returns
0成功,非0不成功
-
int f_flush_wbuf(const char *path)
刷新文件系统缓存buf
- Parameters
path – 设备路径
- Returns
0成功,非0不成功
-
struct vfs_partition
- #include <fs.h>
分区信息
-
struct ffolder
- #include <fs.h>
文件夹信息
-
struct imount
- #include <fs.h>
挂载点信息
-
struct vfs_attr
- #include <fs.h>
文件属性
-
struct FILE
- #include <fs.h>
文件流
-
struct vfscan
- #include <fs.h>
文件扫描信息
Public Members
-
u8 scan_file
是否扫描文件
-
u8 subpath
子目录,设置是否只扫描一层
-
u8 scan_dir
是否扫描目录
-
u8 attr
文件属性
-
u8 cycle_mode
扫描的循环模式
-
char sort
扫描的文件排序 ‘t’ ‘n’
-
char ftype[20 * 3 + 1]
扫描的文件扩展类型
-
u16 file_number
扫描出来的文件总数
-
u16 file_counter
当前文件序号
-
u16 dir_totalnumber
文件夹总数
-
u16 musicdir_counter
播放文件所在文件夹序号
-
u16 fileTotalInDir
文件夹下的文件数目
-
void *priv
私有指针
-
struct vfs_devinfo *dev
设备信息
-
struct vfs_partition *part
分区信息
-
char filt_dir[12]
设置文件夹过滤
-
u8 scan_file