⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 一个基于单片机的小型操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************************
*                 东软培训中心教学项目:基于ARM和uc/os-II的PDA系统
*
*                      (c) Copyright 2005, 东软培训中心
*                             All Rights Reserved
*
* 模块名称:文件操作模块
* 文件名:FILE.C
* 作者:朱成果,孙周旋
* 时间:2005年9月20日
* 版本:V0.01
**********************************************************************************************************************
*/
#include "driven.h"
#include "uhal.h"
#include <stdio.h>

FILECNT flashfile;								//文件结构变量
//RECLIST numturm[100];

unsigned char DIRBUFF[528];						//路径存储区
int cluster,file_length;						//簇号和文件长度
//int term_length;
unsigned char buffer[100];						//保存一条联系记录(name,telnum,plmnum,mail)
unsigned char BLOCKBUFF[0x4200];	//用来保存文件控制块信息
 
extern void Flash_Reset(void);															//flash reset
extern unsigned char Erase_Cluster(unsigned int cluster);								//擦除簇内容
extern void ReadPage(unsigned int block,unsigned int page,unsigned char *pPage);		//读取一个页面
extern int WritePage(unsigned int block,unsigned int page,U8 *pPage);					//写回一个页面



int DeleteFile(char[]);																	//删除文件
FILECNT * OpenFile(char filename[],U32 OpenMode);										//打开文件
int FindFile(char[]);
U32 ReadFile(FILECNT * file,U8 * ReadBuffer,U32 nReadByte);								//读取文件
RECLIST GetToken(void);																	//获取记录的TOKEN
int GetLine(unsigned char buffer[],int line);											//找到要操作的记录的首字符索引
void clearBuffer(void);																	//清空记录缓冲区
int InsertALine(FILECNT * file,char filename[],RECLIST rcd);							//插入一行记录
/*
**********************************************************************************************************************
*                       OPENFILE
*
* 作者:胡仲华
*
* 时间:2007年7月4日
*
* 描述:从电子硬盘中找到PHONENUM.TXT文件所在的Block,并打开,设置文件打开模式为OpenMode。
*	 
* 参数:filename:要打开的文件的名称,OpenMode文件打开的方式。
*
* 返回值:文件指针。
***********************************************************************************************************************
*/

FILECNT * OpenFile(char filename[],U32 OpenMode){
	unsigned int i,j;								//控制变量
	U8* p;				
	Flash_Reset();									//flash reset
	i=FindFile(filename);							//按文件名查找文件
	if (i==FALSE)									//如果没找到,返回空文件指针
	{
		Uart_Printf("error");						//打印错误
		return (FILECNT *)0;
	}
	
	j=cluster*2-1;									//找到存放数据的簇地址

	p=flashfile.Buffer;		
	
	for (i=0;i<32;i++)
	{
		ReadPage(j,i,p);							//读取文件内容到缓冲区
		p += 528;									//指向下一个页面
	}
	
	flashfile.filemode =OpenMode;					//将文件打开方式置为想要的模式
	return &flashfile;								//返回文件结构指针
		
}


/*
**********************************************************************************************************************
*                       FINDFILE
*
* 作者:朱成果,胡仲华修改
*
* 时间:2007年7月4日
*
* 描述:从电子硬盘中找到PHONENUM.TXT文件所在的Block。
*	 
* 参数:filename要找的文件的名称。
*
* 返回值:TRUE:找到文件;FALSE:没有找到;文件长度在外部变量file_length,文件簇号在外部变量cluster。
***********************************************************************************************************************
*/
int FindFile(char filename[])
{
	int i,j;
	U8* pdirname;									//指向路径
	BOOL find;										//是否找到
	
	ReadPage(1,5,DIRBUFF);	
	find = FALSE;
	
		for (j=0;j<16;j++)
		{
			pdirname = DIRBUFF + j*32;				//找到文件的具体位置
			for (i=0;i<11;i++)
			{
				if(filename[i] == *pdirname)		//将文件名与簇内的文件内容相比较,找到正确的文件存在位置
		   			pdirname +=1;
				else
				{
					find = FALSE;					//如果找不到匹配的,返回FALSE
					break;
				}
			}
			if(i==11)
			{
				pdirname += 0x0f;
				cluster = *(pdirname+1)*256 + *pdirname;													//得出文件所在的位置
				i = *(pdirname+2) + *(pdirname+3)*(1<<8)+ *(pdirname+4)*(1<<16)+ *(pdirname+5)*(1<<24);		//得到文件的大小
				find=TRUE;																					//找到文件
				break;
			}
		}
		
	flashfile.fileblock = cluster;		//将文件结构体指针的fileblock赋给相应的值
	flashfile.filesize  = i;			//将文件结构体指针的filesize赋给相应的值
	return(find);	
}

/*
**********************************************************************************************************************
*                       READFILE
*
* 作者:朱成果 胡仲华修改
*
* 时间:2007年7月4日
*
* 描述:从所给的文件中读取给定的某一行记录的信息
*	 
* 参数:filename:要读取的文件名称,ReadBuffer:读取数据缓冲区,nReadByte:要读取的文件行。
*
* 返回值:整型,-1表示读取失败,非负数表示读取成功
***********************************************************************************************************************
*/

U32 ReadFile(FILECNT * file,U8 * ReadBuffer,U32 nReadByte)
{
	
	int index1=0;									//当前需要读取的记录在文件的Buffer中的索引
	int index2=0;									//一条记录读取到的位置
	U8 * current;									//当前需要读取的记录在文件的Buffer中的当前位置
	if(file==(FILECNT *)0){							//如果文件不存在,返回-1
		return -1;
	}
	current = (*file).Buffer;								//如果文件存在,将current指向文件缓冲区的开头
	index1 = GetLine(current,nReadByte);					//得到当前需要读取的记录的索引位置
	current = current+index1;								//将current移动到当前要读取的地方
	clearBuffer();											//清空存放一条记录的缓冲区
	while(*current!='\n'){									//如果没有遇到一条记录结束
		if(index1%528<512){									//如果当前读取到的地方是页面内存放数据的有效读取区
			buffer[index2] = *current;						//将读到的字符推进缓冲区
			index2++;										//缓冲区索引向后移
		}
		current++;											//当前指针指向下一个要读取的字符的位置
		index1++;											//索引也加一
		
	}
	
	buffer[index2] = ',';			
	buffer[index2+1] = '#';									//以“,#”作为一条记录的结束标记
	ReadBuffer = buffer;		
	return index1;											//返回当前索引					
}

/*
**********************************************************************************************************************
*                       WRITEFILE
*
* 作者:朱成果
*
* 时间:2005年10月19日
*
* 描述:把DATABUFF中的数据写到PHONENUM.TXT所在的Block。
*	 
* 参数:无,要求在调用此函数前把要写入的字节数赋值给全局变量file_length。
*
* 返回值:TRUE:找到文件,文件簇号在外部变量cluster;FALSE:没有找到。
***********************************************************************************************************************
*/



U8 WriteFile(char filename[],U8 * WriteBuffer,U32 nWriteyte)
{
	int a;
	unsigned int i,j;
	unsigned char k;
	
	U8* pdirname;
	U8* p;
	Flash_Reset();			//flash reset
	FindFile(filename);		//查找文件是否存在
	
	if (i==FALSE)			//if there is the filename
	{
		return(i);			// 存在,返回FALSE
	}
	
	j=1;			
	p=BLOCKBUFF;			//将控制块信息读取到BLOCKBUFF中
	for (i=0;i<32;i++)
	{
		ReadPage(j,i,p);	//按页读取
		p += 528;
	}
	
	for (j=0;j<16;j++)										//在一个簇中查找需要写的文件
		{
			pdirname =&BLOCKBUFF[0xa50] + j*32;				//确定开始查找位置
			for (i=0;i<11;i++)
			{
				if(filename[i] == *pdirname)
		   			pdirname +=1;
				else
				{
					return FALSE;
					break;									//没找到,返回FALSE
				}
			}
			if(i==11)
			{												//将文件的长度存如控制块
				pdirname += 0x11;
				*pdirname = (U8)nWriteyte&0xff;
				*(pdirname+1) = (U8)(nWriteyte>>8)&0xff;
				*(pdirname+2) = (U8)(nWriteyte>>16)&0xff;
				*(pdirname+3) = (U8)(nWriteyte>>24)&0xff;
				break;
			}
		}
	j=1;
	k = Erase_Cluster(1);									//erase the control block
	
	p=BLOCKBUFF;											//将控制块信息写回控制块所在地方
	
	for (i=0;i<32;i++)		
	{
		a = WritePage(j,i,p);								//按页写回
		p += 528;
	}
	
	j=cluster*2-1;			
	k = Erase_Cluster(j);									//擦除原数据区
	
	p=WriteBuffer;											//将文件的数据块写回文件的数据区
	
	for (i=0;i<32;i++)
	{
		a = WritePage(j,i,p);								//按页写回
		p += 528;
	}
	
   return(TRUE);
}


/*
**********************************************************************************************************************
*                       DELETEFILE
*
* 作者:胡仲华
*
* 时间:2007年7月4日
*
* 描述:根据文件名filename删除某个文件
*	 
* 参数:需要删除的文件的文件名
*
* 返回值:0或者1,0失败,1成功
***********************************************************************************************************************
*/

int DeleteFile(char filename[]){
	
	return 0;
}


/*
**********************************************************************************************************************
*                       CLOSEFILE
*
* 作者:孙周旋
*
* 时间:2007年7月4日
*
* 描述:关闭文件
*	 
* 参数:pfile文件指针,如果文件未打开,不做任何操作,
*	如果文件打开,那么关闭文件,其实就是清空文件在缓冲区中的数据内容
*
* 返回值:0或者1,0失败,1成功
***********************************************************************************************************************
*/
int CloseFile(FILECNT* pfile){
	pfile = (FILECNT*)0;
	return 0;
}

/*
**********************************************************************************************************************
*                       GETLINE
*
* 作者:胡仲华
*
* 时间:2007年7月4日
*
* 描述:读取某一给定的缓存区中具体某一行,返回该行第一个字符的索引
*	 
* 参数:ReadBuffer:指向需要查找给定的行的记录的文件的指针,line:需要查找首字母索引的行号。
*
* 返回值:
*	类型:整型
	描述:某一行的首字母索引
***********************************************************************************************************************
*/

int GetLine(U8 * ReadBuffer,int line){
	int index=0;										//缓冲区的索引
	int currentLine =0;									//当前读取到的行号	
	U8 * current;										//当前读取到的文件数据缓冲区的位置
								
	if(line<=0){										//如果需要读取的行号小于0,那么就直接返回文件开头
		return 0;
	}
	current = ReadBuffer;									//指向缓冲区开头
	while(*current!='#'){									//如果没有读取到文件结尾
		if(*current=='\n'&&*(current+1)!='\n'){				//如果读取到的字符是换行
			currentLine++;									//当前读取行号加一
		}
		
		if(currentLine==line){								//如果当前行号值与需要读取的行号值一样,那么将索引置为下一行的首字符索引。
			index++;
			break;											//返回索引
		}
		
		index++;											//如果还没有读取到要读取到的行,索引和指向指针加一,指向下一个字符
		current++;
		
		
	}
	return index;											//返回索引值
	
}


/*
**********************************************************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -