【rtthread番外】第一篇:文件系统dfs

一、文件系统概念

文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型 (Abstract datatype),是一种用于向用户提供底层数据访问的机制。
在 RT-Thread DFS 中,文件系统有统一的根目录,使用 / 来表示。而在根目录下的 f1.bin 文件则使用 /f1.bin 来表示, 2018 目录下的 f1.bin 目录则使用 /data/2018/f1.bin 来表示。即目录的分割符号是 /,这与 UNIX/Linux 完全相同,与 Windows 则不相同(Windows 操作系统上使用 \ 来作为目录的分割符)。

二、文件系统api

2.1 文件系统挂载api

//初始化文件系统组件
dfs_init() 

//注册文件系统,初始化相应文件系统时自动调用
/*
ops:文件系统操作结构体指针
返回:0:成功
       -1:失败
*/
int dfs_register(const struct dfs_filesystem_ops *ops);

//格式化文件系统
/*
fs_name:文件系统类型,可取
    elm elm-FAT 文件系统
    jffs2 jffs2 日志闪存文件系统
    nfs NFS 网络文件系统
    ram RamFS 文件系统
    rom RomFS 只读文件系统
    uffs uffs 文件系统
device_name:块设备名称
*/
int dfs_mkfs(const char * fs_name, const char * device_name);

//挂载文件系统
/*
device_name:块设备名称
path:挂载路径
filesystemtype:同dfs_mkfs的fs_name
rwflag:读写标志
data:文件系统的私有数据
*/
int dfs_mount(const char *device_name,
                    const char *path,
                    const char *filesystemtype,
                    unsigned long rwflag,
                    const void *data);

//卸载文件系统
/*
specialalfile:挂载路径,同dfs_mount的path
*/
int dfs_unmount(const char *specialfile);

2.2 文件管理api

//打开或者创建一个文件
/*
file:文件名
flags:打开方式,可取
    O_RDONLY 只读方式打开文件
    O_WRONLY 只写方式打开文件
    O_RDWR 以读写方式打开文件
    O_CREAT 如果要打开的文件不存在,则建立该文件
    O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的
    方式添加到文件的尾部
    O_TRUNC 如果文件已经存在,则清空文件中的内容
返回:文件描述符
*/
int open(const char *file, int flags, ...);

//关闭文件
/*
fd:文件描述符
*/
int close(int fd);

//读取文件
/*
fd:文件描述符
buf:读取缓冲区指针
len:读取长度,单位:字节
返回:int :实际读取的字节数
        0:读取已达结尾或无数据可读
       -1:读取出错
*/
int read(int fd, void *buf, size_t len);

//写文件
/*
fd:文件描述符
buf:写缓冲区指针
len:写入文件的数据大小,单位:字节
*/
int write(int fd, const void *buf, size_t len);

//重命名
/*
old:旧文件名
new:新文件名
*/
int rename(const char *old, const char *new);

//获取文件状态
/*
file:文件名
buf:文件信息结构体指针
*/
int stat(const char *file, struct stat *buf);

//删除文件
/*
pathname:文件路径+文件名
*/
int unlink(const char *pathname);

//同步数据到存储设备
/*
fildes:文件描述符
*/
int fsync(int fildes);

//查询文件系统相关信息
/*
path:挂载路径
buf:文件系统信息结构体指针
*/
int statfs(const char *path, struct statfs *buf);

//监视IO设备是否有事件发生
/*
nfds 集合中所有文件描述符的范围,即所有文件描述符的最大值加 1
readfds 需要监视读变化的文件描述符集合
writefds 需要监视写变化的文件描述符集合
exceptfds 需要监视出现异常的文件描述符集合
timeout select 的超时时间
*/
int select( int nfds,
            fd_set *readfds,
            fd_set *writefds,
            fd_set *exceptfds,
            struct timeval *timeout);

2.3 目录管理api

//创建目录
/*
path:目录绝对路径
mode:创建模式:默认填入0x777
*/
int mkdir(const char *path, mode_t mode);

//删除目录
/*
pathname:目录的绝对路径
*/
int rmdir(const char *pathname);

//打开目录
/*
name:目录的绝对路径
返回DIR:目录流指针
*/
DIR* opendir(const char* name);

//关闭目录
/*
d:目录流指针
*/
int closedir(DIR* d);

//读取目录
/*
d:目录流指针
dirent:目录条目结构体
*/
struct dirent* readdir(DIR *d);

//获取目录流当前位置
/*
d:目录流
返回long:目录流位置
*/
long telldir(DIR *d);

//设置目录流位置
/*
d:目录流
offset:偏移,可以由telldir获取
*/
void seekdir(DIR *d, off_t offset);

//重设目录流到开头
/*
d:目录流
*/
void rewinddir(DIR *d);

三、文件系统示例

本示例为设置目录流示例。

#include <rtthread.h>
#include <dfs_posix.h> /* 当 需 要 使 用 文 件 操 作 时, 需 要 包 含 这 个 头 文 件 */
/* 假 设 文 件 操 作 是 在 一 个 线 程 中 完 成 */
static void telldir_sample(void)
{
    
    
	DIR *dirp;
	int save3 = 0;
	int cur;
	int i = 0;
	struct dirent *dp;
	/* 打 开 根 目 录 */
	rt_kprintf("the directory is:\n");
	dirp = opendir("/");
	for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
	{
    
    
		/* 保 存 第 三 个 目 录 项 的 目 录 指 针 */
		i++;
		if (i == 3)
		save3 = telldir(dirp);
		rt_kprintf("%s\n", dp->d_name);
	}
	/* 回 到 刚 才 保 存 的 第 三 个 目 录 项 的 目 录 指 针 */
	seekdir(dirp, save3);
	/* 检 查 当 前 目 录 指 针 是 否 等 于 保 存 过 的 第 三 个 目 录 项 的 指 针. */
	cur = telldir(dirp);
	if (cur != save3)
	{
    
    
		rt_kprintf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur);
	}
	/* 从 第 三 个 目 录 项 开 始 打 印 */
	rt_kprintf("the result of tell_seek_dir is:\n");
	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
	{
    
    
		rt_kprintf("%s\n", dp->d_name);
	}
	/* 关 闭 目 录 */
	closedir(dirp);
}
/* 导 出 到 msh 命 令 列 表 中 */
MSH_CMD_EXPORT(telldir_sample, telldir sample);

Guess you like

Origin blog.csdn.net/weixin_43810563/article/details/117092314