📄 file.c
字号:
/*
*********************************************************************************************************************
* 东软培训中心教学项目:基于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 + -