file.c

来自「Atmega64单片机程序(完整工程)」· C语言 代码 · 共 765 行 · 第 1/2 页

C
765
字号

#define   IN_FILE 

#include "SYS_Config.h" 
#include "SD_Drive.h" 
#include "fat.h" 
#include "time.h" 


extern INT32U _GetFDTInfo(char *FDTName,char *DirFileName);
extern void strupr(INT8U *Path);

static MY_FILE FileInfo[MAX_OPEN_FILES];/* 打开文件信息表 */


/*********************************************************************************************************
** 函数名称: FileInit
** 功能描述: 初始化文件指针系统
** 输   入: 无
** 输   出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void FileInit(void)
{
    HANDLE i ;
    
    for(i=0;i<MAX_OPEN_FILES;i++)
    {
        FileInfo[i].Flags=0 ;
    }
}

/*********************************************************************************************************
** 函数名称: FindOpenFile
** 功能描述: 查找已打开的指定文件的文件句柄,内部使用
** 输   入: Drive:文件所在的逻辑盘号
**           DirClus:文件所在目录的开始簇号
**           FileName:内部文件名
** 输   出: 文件句柄,Not_Open_FILE为没有打开
** 全局变量: FileInfo
** 调用模块: _GetFDTInfo,GetDrive,FindFDTInfo,
********************************************************************************************************/
HANDLE FindOpenFile(INT8U Drive,INT32U DirClus,char FileName[11])
{
    HANDLE   Rt ;
    MY_FILE  *fp ;
    
    fp=FileInfo ;
    for(Rt=0;Rt<MAX_OPEN_FILES;Rt++)
    {
        if(fp->Flags!=0)
        if(fp->Drive==Drive)
        if(fp->DirClus==DirClus)
        if(fp->Name[0]==FileName[0])
        if(fp->Name[1]==FileName[1])
        if(fp->Name[2]==FileName[2])
        if(fp->Name[3]==FileName[3])
        if(fp->Name[4]==FileName[4])
        if(fp->Name[5]==FileName[5])
        if(fp->Name[6]==FileName[6])
        if(fp->Name[7]==FileName[7])
        if(fp->Name[8]==FileName[8])
        if(fp->Name[9]==FileName[9])
        if(fp->Name[10]==FileName[10])
        {
            break ;
        }
        fp++;
    }
    if(Rt>=MAX_OPEN_FILES)
    {
        Rt=Not_Open_FILE ;
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: RemoveFile
** 功能描述: 删除文件
** 输   入: DirFileName:用户使用的文件名
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: strupr,_GetFDTInfo,GetDrive,FindFDTInfo,FATDelClusChain,DelFDT
********************************************************************************************************/
INT8U RemoveFile(char *DirFileName)
{
    INT32U ClusIndex,ClusIndex1 ;
    INT8U  Drive,Rt ;
    char   DirName[12];
    FDT    temp ;
    
    strupr(DirFileName);
    /* 变为大写 */
    ClusIndex=_GetFDTInfo(DirName,DirFileName);
    Rt=PATH_NOT_FIND ;
    if(ClusIndex!=BAD_CLUS)
    {
        Drive=GetDrive(DirFileName);
        /* 获取文件所在逻辑盘号 */
        Rt=FindFDTInfo(&temp,Drive,ClusIndex,DirName);
        if(Rt==RETURN_OK)
        {
            Rt=NOT_FIND_FILE ;
            /* 是文件才删除 */
            if((temp.Attr&ATTR_DIRECTORY)==0)
            {
                Rt=FILE_LOCK ;
                if(FindOpenFile(Drive,ClusIndex,DirName)<MAX_OPEN_FILES)
                {
                    /* 文件没有打开才删除 */
                    ClusIndex1=temp.FstClusLO+((INT32U)(temp.FstClusHI)<<16);
                    FATDelClusChain(Drive,ClusIndex1);
                    Rt=DelFDT(Drive,ClusIndex,DirName);
                }
            }
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FindOpenFileW
** 功能描述: 查找以读写方式打开的指定文件的文件句柄,内部使用
** 输   入: Drive:文件所在的逻辑盘号
**           DirClus:文件所在目录的开始簇号
**           FileName:内部文件名
** 输   出: 文件句柄,Not_Open_FILE为没有打开
** 全局变量: FileInfo
** 调用模块: _GetFDTInfo,GetDrive,FindFDTInfo,
********************************************************************************************************/
HANDLE FindOpenFileW(INT8U Drive,INT32U DirClus,char FileName[11])
{
    HANDLE Rt ;
    MY_FILE *fp ;
    
    fp=FileInfo ;
    for(Rt=0;Rt<MAX_OPEN_FILES;Rt++)
    {
        if((fp->Flags&FILE_FLAGS_WRITE)!=0)
        if(fp->Drive==Drive)
        if(fp->DirClus==DirClus)
        if(fp->Name[0]==FileName[0])
        if(fp->Name[1]==FileName[1])
        if(fp->Name[2]==FileName[2])
        if(fp->Name[3]==FileName[3])
        if(fp->Name[4]==FileName[4])
        if(fp->Name[5]==FileName[5])
        if(fp->Name[6]==FileName[6])
        if(fp->Name[7]==FileName[7])
        if(fp->Name[8]==FileName[8])
        if(fp->Name[9]==FileName[9])
        if(fp->Name[10]==FileName[10])
        {
            break ;
        }
        fp++;
    }
    if(Rt>=MAX_OPEN_FILES)
    {
        Rt=Not_Open_FILE ;
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: _FileOpenR
** 功能描述: 只读方式打开文件,内部使用
** 输   入: DirFileName:用户使用的文件名
** 输   出: 文件句柄,Not_Open_FILE为不能打开
** 全局变量: FileInfo
** 调用模块: _GetFDTInfo,GetDrive,FindFDTInfo,
********************************************************************************************************/
HANDLE _FileOpenR(char *DirFileName)
{
    MY_FILE *fp ;
    HANDLE Rt ;
    FDT FileFDT ;
    
    /* 查找空闲文件登记项 */
    for(Rt=0;Rt<MAX_OPEN_FILES;Rt++)
    {
        if(FileInfo[Rt].Flags==0)
        {
            break ;
        }
    }
    
    if(Rt<MAX_OPEN_FILES)
    {
        fp=FileInfo+Rt ;
        
        /* 获取目录开始簇号和文件名 */
        fp->DirClus=_GetFDTInfo(fp->Name,DirFileName);
        if(fp->DirClus<BAD_CLUS)
        {
            fp->Drive=GetDrive(DirFileName);/* 获取文件所在逻辑盘号 */
            
            /* 获取文件信息 */
            if(FindFDTInfo(&FileFDT,fp->Drive,fp->DirClus,fp->Name)==RETURN_OK)
            {
                if((FileFDT.Attr&ATTR_DIRECTORY)==0)
                {
                    fp->Flags=FILE_FLAGS_READ ;
                    fp->FileSize=FileFDT.FileSize ;
                    fp->FstClus=((INT32U)FileFDT.FstClusHI<<16)+FileFDT.FstClusLO ;
                    fp->Clus=fp->FstClus ;
                    fp->Offset=0 ;
                    return Rt ;
                }
            }
        }
    }
    return Not_Open_FILE ;
}

/*********************************************************************************************************
** 函数名称: _FileOpenW
** 功能描述: 只写方式打开文件,内部使用
** 输   入: DirFileName:用户使用的文件名
** 输   出: 文件句柄,Not_Open_FILE为不能打开
** 全局变量: FileInfo
** 调用模块: _GetFDTInfo,GetDrive,FindFDTInfo,
********************************************************************************************************/
HANDLE _FileOpenW(char *DirFileName)
{
    MY_FILE *fp ;
    FDT temp ;
    HANDLE Rt ;
    INT8U i ;
    
    for(Rt=0;Rt<MAX_OPEN_FILES;Rt++)
    {
        if(FileInfo[Rt].Flags==0)
        {
            break ;
        }
    }
    
    if(Rt<MAX_OPEN_FILES)
    {
        fp=FileInfo+Rt ;
        
        fp->DirClus=_GetFDTInfo(fp->Name,DirFileName);/* 获取目录开始簇号和文件名 */
        if(fp->DirClus<BAD_CLUS)
        {
            fp->Drive=GetDrive(DirFileName);/* 获取文件所在逻辑盘号 */
            
            /* 文件已经以读写方式打开,不能再次以读写方式打开 */
            if(FindOpenFileW(fp->Drive,fp->DirClus,fp->Name)==Not_Open_FILE)
            {
                if(FindFDTInfo(&temp,fp->Drive,fp->DirClus,fp->Name)==RETURN_OK)
                {
                    if((temp.Attr&ATTR_DIRECTORY)!=0)
                    {
                        return Not_Open_FILE ;
                    }
                    /* 删除文件 */
                    if(RemoveFile(DirFileName)!=RETURN_OK)
                    {
                        return Not_Open_FILE ;
                    }
                }
                /* 创建文件 */
                for(i=0;i<11;i++)
                {
                    temp.Name[i]=fp->Name[i];
                }
                temp.Attr=0 ;
                temp.FileSize=0 ;
                
                temp.NTRes=0 ;
                temp.CrtTimeTenth=time_getTime();
                temp.CrtTime=time_getTime();
                temp.CrtDate=time_getDate();
                temp.LstAccDate=time_getDate();
                temp.WrtTime=time_getTime();
                temp.WrtDate=time_getDate();
                
                temp.FstClusLO=0 ;
                temp.FstClusHI=0 ;
                /* 增加文件 */
                if(AddFDT(fp->Drive,fp->DirClus,&temp)==RETURN_OK)
                {
                    /* 设置文件信息 */
                    fp->Flags=FILE_FLAGS_READ|FILE_FLAGS_WRITE ;
                    fp->FileSize=0 ;
                    fp->FstClus=0 ;
                    fp->Clus=0 ;
                    fp->Offset=0 ;
                    return Rt ;
                }
            }
        }
    }
    return Not_Open_FILE ;
}

/*********************************************************************************************************
** 函数名称: _FileOpenRW
** 功能描述: 只读写方式打开文件,内部使用
** 输   入: DirFileName:用户使用的文件名
** 输   出: 文件句柄,Not_Open_FILE为不能打开
** 全局变量: 无
** 调用模块: _FileOpenR,_FileOpenW
********************************************************************************************************/
HANDLE _FileOpenRW(char *DirFileName)
{
    HANDLE Rt ;
    
    Rt=_FileOpenR(DirFileName);
    if(Rt==Not_Open_FILE)
    {
        Rt=_FileOpenW(DirFileName);
    }
    else 
    {
        if(FindOpenFileW(FileInfo[Rt].Drive,FileInfo[Rt].DirClus,FileInfo[Rt].Name)==Not_Open_FILE)
        {
            FileInfo[Rt].Flags|=(FILE_FLAGS_WRITE|FILE_FLAGS_READ);
        }
        else 
        {
            FileInfo[Rt].Flags=0 ;
            Rt=Not_Open_FILE ;
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FileOpen
** 功能描述: 以指定方式打开文件
** 输   入: DirFileName:用户使用的文件名
**           Type:打开方式
** 输   出: 文件句柄,Not_Open_FILE为不能打开
** 全局变量: 无
** 调用模块: _FileOpenR,_FileOpenW,_FileOpenRW
********************************************************************************************************/
HANDLE FileOpen(char *DirFileName,char *Type)
{
    HANDLE Rt ;
    
    Rt=Not_Open_FILE ;
    strupr(Type);
    strupr(DirFileName);
    if(Type[0]=='R')
    {
        if(Type[1]=='W')
        {
            Rt=_FileOpenRW(DirFileName);
        }
        else 
        {
            Rt=_FileOpenR(DirFileName);
        }
        return Rt ;
    }
    if(Type[0]=='W')
    {
        if(Type[1]=='R')
        {
            Rt=_FileOpenRW(DirFileName);
        }
        else 
        {
            Rt=_FileOpenW(DirFileName);
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FileClose
** 功能描述: 关闭指定文件
** 输   入: Handle:文件句柄
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT8U FileClose(HANDLE Handle)

⌨️ 快捷键说明

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