file.c

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

C
765
字号
{
    INT8U Rt ;
    FDT FileFDT ;
    MY_FILE *fp ;
    
    Rt=PARAMETER_ERR ;
    if(Handle>=0&&Handle<MAX_OPEN_FILES)
    {
        Rt=RETURN_OK ;
        fp=FileInfo+Handle ;
        if((fp->Flags&FILE_FLAGS_WRITE)==FILE_FLAGS_WRITE)
        {
            Rt=FindFDTInfo(&FileFDT,fp->Drive,fp->DirClus,fp->Name);
            if(Rt==RETURN_OK)
            if(FileFDT.FileSize<fp->FileSize)
            {
                FileFDT.FileSize=fp->FileSize ;
                if(FileFDT.FstClusLO==0)
                if(FileFDT.FstClusHI==0)
                {
                    FileFDT.FstClusLO=fp->FstClus&0xffff ;
                    FileFDT.FstClusHI=(fp->FstClus>>16)&0xffff ;
                }
                ChangeFDT(fp->Drive,fp->DirClus,&FileFDT);
            }
        }
        fp->Flags=0 ;
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FileGetCh
** 功能描述: 从文件读一个字节
** 输   入: Ch:返回读到的数据
**           Handle:文件句柄
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT8U FileGetCh(INT8U *Ch,HANDLE Handle)
{
    INT32U i,j,SecIndex ;
    MY_FILE *fp ;
    Disk_Info *DiskInfo ;
    INT8U Rt ;
    INT8U *Buf ;
    
    Rt=PARAMETER_ERR ;
    fp=FileInfo+Handle ;
    /* Handle是否有效 */
    /* 对应的打开文件信息表是否已使用 */
    if(Handle>=0&&Handle<MAX_OPEN_FILES)
    if(fp->Flags!=0)
    {
        Rt=FILE_EOF ;
        if(fp->Offset>=fp->FileSize)
        {
            /* 如果读数据超出文件的长度,看一看谁否有别的程序正在写这个文件 */
            /* 如果有,则可能文件的长度有变化,更正之*/
            Handle=FindOpenFileW(fp->Drive,fp->DirClus,fp->Name);
            if(Handle<MAX_OPEN_FILES)
            {
                fp->FileSize=FileInfo[Handle].FileSize ;
                if(fp->Offset==0)
                {
                    fp->FstClus=FileInfo[Handle].FstClus ;
                    fp->Clus=FileInfo[Handle].Clus ;
                }
            }
        }
        Rt=FILE_EOF ;
        /* 是否到文件结束 */
        if(fp->Offset<fp->FileSize)
        {
            Rt=NOT_FIND_DISK ;
            /* 获取文件所在逻辑盘信息 */
            DiskInfo=GetDiskInfo(fp->Drive);
            if(DiskInfo!=NULL)
            {
                /* 计算数据所在扇区 */
                j=fp->Offset%(DiskInfo->SecPerClus*DiskInfo->BytsPerSec);
                i=j/DiskInfo->BytsPerSec ;
                j=j%DiskInfo->BytsPerSec ;
                SecIndex=(fp->Clus-2)*DiskInfo->SecPerClus+
                DiskInfo->DataStartSec+i ;
                Rt=SECTOR_READ_ERR ;
                /* 打开扇区 */
                Buf=OpenSec(fp->Drive,SecIndex);
                if(Buf!=NULL)
                {
                    /* 读取扇区数据 */
                    if(ReadSec(fp->Drive,SecIndex)==RETURN_OK)
                    {
                        /* 读取数据 */
                        *Ch=Buf[j];
                        /* 调整文件指针 */
                        fp->Offset++;
                        j++;
                        if(j>=DiskInfo->BytsPerSec)
                        {
                            i++;
                            if(i>=DiskInfo->SecPerClus)
                            {
                                fp->Clus=FATGetNextClus(fp->Drive,fp->Clus);
                            }
                        }
                        Rt=RETURN_OK ;
                    }
                    /* 关闭扇区 */
                    CloseSec(fp->Drive,SecIndex);
                }
            }
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FileRead
** 功能描述: 读取文件
** 输   入: Buf:保存读回的数据
**           Size:要读的字节数
**           Handle:文件句柄
** 输   出: 实际读到的字节数
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT32U FileRead(void *Buf,INT32U Size,HANDLE Handle)
{
    INT8U *temp ;
    INT32U i ;
    
    temp=(INT8U*)Buf ;
    for(i=0;i<Size;i++)
    {
        if(FileGetCh(temp,Handle)!=RETURN_OK)
        {
            break ;
        }
        temp++;
    }
    return i ;
}

/*********************************************************************************************************
** 函数名称: FilePutCh
** 功能描述: 写一个字节到文件
** 输   入: Ch:要写的数据
**           Handle:文件句柄
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT8U FilePutCh(INT8U Ch,HANDLE Handle)
{
    INT32U i,j,SecIndex ;
    MY_FILE *fp ;
    Disk_Info *DiskInfo ;
    INT8U  Rt ;
    INT8U *Buf ;
    
    Rt=PARAMETER_ERR ;
    fp=FileInfo+Handle ;
    
    if(Handle>=0&&Handle<MAX_OPEN_FILES)/* Handle是否有效 */
    if(((fp->Flags)&FILE_FLAGS_WRITE)!=0)/* 对应的打开文件信息表是否已使用 */
    {
        Rt=FILE_EOF ;
        if(fp->Offset<=fp->FileSize)
        {
            Rt=NOT_FIND_DISK ;
            
            DiskInfo=GetDiskInfo(fp->Drive);/* 获取文件所在逻辑盘信息 */
            if(DiskInfo!=NULL)
            {
                /* 调整文件指针 */
                j=(fp->Offset)%(DiskInfo->SecPerClus*DiskInfo->BytsPerSec);
                
                if(j==0)
                {
                    if(fp->Offset<fp->FileSize)
                    {
                        fp->Clus=FATGetNextClus(fp->Drive,fp->Clus);
                    }
                    else 
                    {
                        i=FATAddClus(fp->Drive,fp->Clus);
                        if(i>=BAD_CLUS)
                        {
                            return DISK_FULL ;
                        }
                        fp->Clus=i ;
                        if(fp->FstClus==EMPTY_CLUS)
                        {
                            fp->FstClus=i ;
                        }
                    }
                }
                
                /* 计算数据所在扇区 */
                i=j/DiskInfo->BytsPerSec ;
                j=j%DiskInfo->BytsPerSec ;
                SecIndex=(fp->Clus-2)*DiskInfo->SecPerClus+DiskInfo->DataStartSec+i ;
                Rt=SECTOR_READ_ERR ;
                
                /* 调整打开文件信息表 */
                fp->Offset++;
                if(fp->Offset>fp->FileSize)
                {
                    fp->FileSize=fp->Offset ;
                }
                
                /* 打开扇区 */
                Buf=OpenSec(fp->Drive,SecIndex);
                if(Buf!=NULL)
                {
                    /* 写扇区数据 */
                    if(ReadSec(fp->Drive,SecIndex)==RETURN_OK)
                    {
                        /* 存储数据 */
                        Buf[j]=Ch ;
                        WriteSec(fp->Drive,SecIndex);
                        Rt=RETURN_OK ;
                    }
                    CloseSec(fp->Drive,SecIndex);
                }
            }
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: FileWrite
** 功能描述: 写文件
** 输   入: Buf:要写的数据
**           Size:要写的字节数
**           Handle:文件句柄
** 输   出: 实际写的字节数
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT32U FileWrite(void *Buf,INT32U Size,HANDLE Handle)
{
    INT8U  *temp ;
    INT32U i ;
    
    temp=(INT8U *)Buf ;
    for(i=0;i<Size;i++)
    {
        if(FilePutCh(*temp,Handle)!=RETURN_OK)
        {
            break ;
        }
        temp++;
    }
    return i ;
}

/*********************************************************************************************************
** 函数名称: FileCloseAll
** 功能描述: 关闭所有打开的文件
** 输   入: 无
** 输   出: 无
** 全局变量: FileInfo
** 调用模块: AllCacheWriteBack
********************************************************************************************************/
void FileCloseAll(void)
{
    INT32U i ;
    
    for(i=0;i<MAX_OPEN_FILES;i++)
    {
        FileClose(i);
    }
    AllCacheWriteBack();
}

/*********************************************************************************************************
** 函数名称: FileEof
** 功能描述: 判断文件是否到读\写到文件尾
** 输   入: Handle:文件句柄
** 输   出: 0:否
**           1:是
** 全局变量: FileInfo
** 调用模块: 无
********************************************************************************************************/
INT8U FileEof(HANDLE Handle)
{
    if(Handle<MAX_OPEN_FILES)
    {
        if(FileInfo[Handle].Offset<FileInfo[Handle].FileSize)
        {
            return FALSE ;
        }
    }
    return TRUE ;
}

/*********************************************************************************************************
** 函数名称: FileSeek
** 功能描述: 移动文件读\写位置
** 输   入: Handle:文件句柄
**           offset:移动偏移量
**           Whence:移动模式SEEK_SET:从文件头计算SEEK_CUR:从当前位置计算SEEK_END:从文件尾计算
** 输   出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT8U FileSeek(HANDLE Handle,INT32S offset,INT8U Whence)
{
    INT8U Rt ;
    INT32U i,Clus ;
    MY_FILE   *fp ;
    Disk_Info *DiskInfo ;
    
    Rt=PARAMETER_ERR ;
    fp=FileInfo+Handle ;
    
    if(Handle>=0&&Handle<MAX_OPEN_FILES)/* Handle是否有效 */
    if(fp->Flags!=0)/* 对应的打开文件信息表是否已使用 */
    {
        Rt=RETURN_OK ;
        switch(Whence)
        {
            case SEEK_END :/* 从文件尾计算 */
                 fp->Offset=fp->FileSize-offset ;
                 offset=-offset ;
                 break ;
            case SEEK_SET :
                 fp->Offset=offset ;
                 break ;
            case SEEK_CUR :/* 从当前位置计算 这里不用break是正确的*/
                 i=fp->Offset+offset ;
                 break ;
            default :
                 Rt=PARAMETER_ERR ;
                 break ;
        }
        /* 改变当前簇号 */
        if(Rt==RETURN_OK)
        {
            if(fp->Offset>fp->FileSize)
            {
                if(offset>0)
                {
                    fp->Offset=fp->FileSize ;
                }
                else 
                {
                    fp->Offset=0 ;
                }
            }
            Rt=NOT_FIND_DISK ;
            DiskInfo=GetDiskInfo(fp->Drive);
            if(DiskInfo!=NULL)
            {
                Rt=RETURN_OK ;
                i=fp->Offset/(DiskInfo->BytsPerSec*DiskInfo->SecPerClus);
                Clus=fp->FstClus ;
                for(;i!=0;i--)
                {
                    Clus=FATGetNextClus(fp->Drive,Clus);
                    if(Clus>=BAD_CLUS)
                    {
                        Rt=FAT_ERR ;
                        break ;
                    }
                }
                fp->Clus=Clus ;
            }
        }
    }
    return Rt ;
}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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