📄 file.c
字号:
{
uint32_t buffing_len; //读缓冲区内的数据长度
struct rw_para *pl_read_para = (struct rw_para *)read_para;
uint32_t read_len; //需要读取的数据长度
sint64_t stock_size;
uint32_t result;
struct file_rsc *fp = (struct file_rsc *)file;
struct st_DBX_device_tag *DBX_device_tag;
DBX_device_tag = (struct st_DBX_device_tag*)
DBX_lhdl->dev_interfase->private_tag;
read_len = pl_read_para->nmemb * pl_read_para->size;
//查询物理设备有多少数据可读,文件尺寸并不可靠,不能用
stock_size = DBX_device_tag->query_file_stocks(fp);
if(stock_size >= read_len)
{//物理设备上有足够的数据
//读取物理设备
result = DBX_device_tag->read(fp,(uint8_t*)buf,read_len);
result = result / pl_read_para->nmemb;
}else
{//物理设备上没有足够的数据,需要调整读取数量,以确保读到整数个单元
read_len = (stock_size / pl_read_para->nmemb) * pl_read_para->nmemb;
//需要从物理设备读取的数据字节数
read_len = read_len * pl_read_para->size;
//读取物理设备
result = DBX_device_tag->read(fp,(uint8_t*)(buf+buffing_len),read_len);
result = result / pl_read_para->nmemb;
}
return result;
}
//----测试字符串是否包含文件柜名-----------------------------------------------
//功能: 测试给定的字符串是否包含文件柜名
//参数: fullname,待检查的字符串
//返回: 含文件柜名,则返回文件柜名的长度,否则返回0
//备注: 内部函数,调用前先确保fullname是合法的字符串。
//----------------------------------------------------------------------------
uint16_t __djyfs_if_contain_DBX_name(char *fullname)
{
uint16_t offset;
for(offset = 0; offset < cn_DBX_name_limit+1; offset++)
{
if(fullname[offset] == ':')
return offset;
}
return 0;
}
//----测试目录串是否绝对路径--------------------------------------------------
//功能: 测试目录串是否绝对路径
//参数: fullname,待检查的字符串
//返回: true = fullname是绝对路径,false = 不是绝对路径
//备注: 内部函数,调用前先确保fullname是合法的字符串。
//----------------------------------------------------------------------------
bool_t __djyfs_if_abs_path(char *fullname)
{
if(fullname[0] == '\\')
{
return true;
}else
{
if(__djyfs_if_contain_DBX_name(fullname) != 0)
return true;
else
return false;
}
}
//----测试目录串是否包含文件名--------------------------------------------------
//功能: 测试目录串是否包含文件名
//参数: fullname,待检查的字符串
//返回: true = fullname包含文件名,false = 不包含文件名
//备注: 内部函数,调用前先确保fullname是合法的字符串。
//----------------------------------------------------------------------------
bool_t __djyfs_if_contain_filename(char *fullname)
{
//fullname是已经经过字符串长度合法性检查的指针
if(fullname[strlen(fullname)-1] != '\\')
return true;
else
return false;
}
//----查看文件(目录)是否已经打开----------------------------------------------
//功能: 查看一个文件(目录)是否已经打开,即看它是否在被打开的文件资源中
//参数: synname,待查的文件(目录)名
//返回: true = 已经打开,false = 未打开(或其他错误)
//备注: 调用前保证fullname是合法的字符串
//----------------------------------------------------------------------------
bool_t __djyfs_item_if_opened(struct st_DBX_device_tag *DBX_device_tag,
char *synname)
{
struct file_rsc *parent,*son;
uint16_t offset,name_len,index=0;
char name[256];
if(__djyfs_if_abs_path(synname))
{
parent = DBX_device_tag->opened_root; //从根目录开始操作
offset = 1;
}else
{
parent = pg_work_path; //从当前路径开始操作
offset = 0;
}
//synname是已经经过字符串长度合法性检查的指针
name_len = strlen(synname);
for( ; offset< name_len; offset++)
{//沿路径逐级查看目录是否已经打开
if(synname[offset] == '\\') //遇到字符'\'
{
name[index] = '\0';
index = 0;
if((son=(struct file_rsc*)rsc_search_son(&parent->file_node,name))
!= NULL)
{//目标已经打开
parent = son; //以当前打开的目录为下次使用的父目录
}else
{
return false;
}
}else //未遇到字符'\'。
{
name[index] = synname[offset]; //复制当前字符到文件名串
index++;
}
if(index >= cn_file_name_limit) //目录名长度超限。
return false;
}
//至此,如果filename传入的是文件名(末字符不是'\'),name保存的是文件名,
//index是串长度,串结束符'\0'未赋值,整个路径都已经打开。
//如果filename出入是目录名,则name保存最后一个目录,且已经打开,index=0。
if(index != 0)
{
name[index] = '\0';
if(rsc_search_son(&parent->file_node,name) != NULL)
{
return true; //文件已经打开
}else
{
return false; //文件尚未打开
}
}else
return true;
}
//----删除文件(目录)----------------------------------------------------------
//功能:删除一个文件(目录),本函数不能删除非空目录,以及只读文件(目录)。要
// 删除只读文件,只有先把它改为非只读文件才能进行。本函数由文件柜的左手
// 控制函数调用,调用顺序:
// 用户调用remove
// -->dev_ctrl
// -->DBX_device->left_hand.io_ctrl
// -->DBX_left_ctrl (用enum_DBX_remove命令)
// -->__djyfs_DBX_remove_item
//参数: DBX_lhdl,被操作的文件柜
// synname,文件名或者目录名字符串,文件和目录统称item
//返回:参考文件系统错误代码列表
//----------------------------------------------------------------------------
uint32_t __djyfs_DBX_remove_item(struct dev_handle *DBX_lhdl,char *synname)
{
struct file_rsc item;
struct st_DBX_device_tag *DBX_device_tag;
DBX_device_tag = (struct st_DBX_device_tag *)
(DBX_lhdl->dev_interfase->private_tag);
if(__djyfs_item_if_opened(DBX_device_tag,synname) == true)
return (uint32_t)enum_fs_object_opened; //不能删除已经打开的对象
if(__djyfs_if_abs_path(synname) == true)
{//synname是当前文件柜的绝对路径
if(!DBX_device_tag->lookfor_item(synname+1,
DBX_device_tag->opened_root,&item))
return (uint32_t)enum_fs_object_nonentity; //被删除的对象不存在
}else
{//synname是相对与 pg_work_path 的相对路径
if(!DBX_device_tag->lookfor_item(synname,pg_work_path,&item))
return (uint32_t)enum_fs_object_nonentity; //被删除的对象不存在
}
item.open_counter = 0; //打开次数清零
item.home_DBX = (struct pan_device*)DBX_lhdl->dev_interfase;
if(item.attr.bits.read_only == true)
return (uint32_t)enum_fs_object_readonly; //不能删除只读对象
if(item.attr.bits.folder)
{//是个目录,需要判断是否空
if(DBX_device_tag->check_folder(&item) != 0)
return (uint32_t)enum_fs_folder_unblank;
}
if(DBX_device_tag->remove_item(&item))
return enum_fs_no_error;
else
return enum_fs_remove_error;
}
//----目录(文件)改名-----------------------------------------------------------
//功能:把一个目录(文件)改名,不允许修改只读目录(文件)的名字,要修改只读文
// 件,必须先修改只读文件的属性,本函数由文件柜的左手控制函数调用,
// 调用顺序:
// 用户调用rename
// -->dev_ctrl
// -->DBX_device->left_hand.io_ctrl
// -->DBX_left_ctrl (用enum_DBX_rename命令)
// -->__DBX_rename_item
//参数: DBX_lhdl,被操作的文件柜
// old_synname,文件或目录原名字符串,
// newname,文件或目录的新名字字符串
//返回:参考文件系统错误代码列表
//----------------------------------------------------------------------------
uint32_t __DBX_rename_item(struct dev_handle *DBX_lhdl,
char *old_synname,char *newname)
{
struct st_DBX_device_tag *DBX_device_tag;
struct file_rsc item;
DBX_device_tag = (struct st_DBX_device_tag *)
(DBX_lhdl->dev_interfase->private_tag);
if(__djyfs_item_if_opened(DBX_device_tag,old_synname) == true)
return enum_fs_object_opened; //不能改名已经打开的对象
if(__djyfs_if_abs_path(old_synname)== true)
{//old_synname是当前文件柜的绝对
if(!DBX_device_tag->lookfor_item(old_synname+1,
DBX_device_tag->opened_root,&item))
return enum_fs_object_nonentity; //被改名的对象不存在
}else
{//old_synname是相对与 pg_work_path 的相对路径
if(!DBX_device_tag->lookfor_item(old_synname,pg_work_path,&item))
return enum_fs_object_nonentity; //被改名的对象不存在
}
if(item.attr.bits.read_only == true)
return enum_fs_object_readonly; //只读文件不允许改名
//newname是已经经过字符串长度合法性检查的指针
if(strlen(newname) <= cn_file_name_limit)//读取文件柜名字
strcpy(item.name,newname);
else
{
memcpy(item.name,newname,cn_file_name_limit);
item.name[cn_file_name_limit] = '\0';
}
if( DBX_device_tag->rename_item(&item))
return enum_fs_no_error;
else
return enum_fs_rename_error;
}
//----关闭文件(目录)----------------------------------------------------------
//功能:关闭一个文件(目录),本函数由文件柜的左手控制函数调用,调用顺序:
// 用户调用fclose
// -->dev_ctrl
// -->DBX_device->left_hand.io_ctrl
// -->DBX_left_ctrl (用enum_DBX_close命令)
// -->__DBX_close_item
//参数:DBX_lhdl,被关闭文件(目录)所属的文件柜
// file,被关闭的文件(目录)指针
//返回:true=成功关闭则,false=失败
//----------------------------------------------------------------------------
bool_t __DBX_close_item(struct dev_handle *DBX_lhdl,struct file_rsc *fp)
{
struct st_DBX_device_tag *DBX_device_tag;
struct file_rsc *parent,*son;
DBX_device_tag =(struct st_DBX_device_tag *)
(DBX_lhdl->dev_interfase->private_tag);
if(fp->attr.bits.folder)
{
if(rsc_get_son(&fp->file_node) != NULL)
return false; //被关闭的目录仍有已经被打开的子项,不能关闭
}
//下面把文件从资源链表中删除,包括已经空的目录
son = fp;
parent = (struct file_rsc *)rsc_get_parent(&son->file_node);
do
{//从被删除结点开始,逐级向上删除空目录。空目录是指资源链表上的空目录结点,
//而物理存储器上该目录可能不是空的
if(son == pg_work_path) //当前工作路径不能被删除
break;
DBX_device_tag->close_item(son);
rsc_del_node(&son->file_node); //从打开文件资源链表中删除结点
mb_free(pg_content_pool,son); //释放结点内存
son = parent; //下一循环释放父结点
parent=(struct file_rsc*)rsc_get_parent(&parent->file_node);//父结点上移
if(DBX_device_tag->opened_sum != 0)
DBX_device_tag->opened_sum --;
}while(son != DBX_device_tag->opened_root); //直到根目录
return true;
}
//----把文件写入到存储器------------------------------------------------------
//功能: 把文件写缓冲区的数据和buf中的数据一起写入到存储器中,并清空写缓冲区。
// 调用顺序:
// 用户调用fflush
// -->dev_ctrl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -