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 + -
显示快捷键?