?? fat.c
字號:
- 隸屬模塊:FAT文件系統模塊
- 函數屬性:內部
- 參數說明:dName:指向文件目錄項的文件名字段的指針
pName:指向轉換完成后的文件名
- 返回說明:無
- 注:此函數配合上面的FilenameMatch函數,就可以實現對文件名通配匹配
***********************************************************************/
void FAT32_toFileName(char *dName,char *pName)
{
char i=7,j=0,k=0;
while(dName[i--]==' ');
for(j=0;j<i+2;j++) pName[j]=L2U(dName[j]);
pName[j++]='.';
i=10;
while(dName[i--]==' ');
k=j+i-6;
i=0;
for(;j<k;j++) pName[j]=dName[8+(i++)];
pName[j]=0;
}
/***********************************************************************
- 功能描述:將字符串中的小寫字符都轉為大寫字符
- 隸屬模塊:FAT文件系統模塊
- 函數屬性:內部
- 參數說明:str:指向待轉換的字符串
- 返回說明:無
- 注:短文件名的情況下,文件名中的字符其實都是大寫字符,為了方便,將文件
名都轉為大寫
***********************************************************************/
void Str2Up(char *str)
{
unsigned char len=strlen(str),i;
for(i=0;i<len;i++)
{
str[i]=L2U(str[i]);
}
}
/**************************************************************************
- 功能描述:進入一個目錄
- 隸屬模塊:FAT文件系統模塊
- 函數屬性:外部,使用戶使用
- 參數說明:path:目錄的路徑 形如:"\\dir1\\dir2\\" ,最后一定是以\\結束
- 返回說明:返回目錄的開始簇號,如果進入目錄失敗,比如目錄不存在,則返回0
- 注:此函數由后面的FAT32_Open_File等函數調用,用來實現打開任意目錄下的文件
不建議用戶調用
**************************************************************************/
UINT32 FAT32_Enter_Dir(INT8 *path)
{
UINT32 Cur_Clust,sec_temp,iSec,iDir,Old_Clust;
UINT8 i=1,counter=0,flag=0;
struct direntry *pDir;
INT8 name[20];
Cur_Clust=pArg->FirstDirClust;
if(path[1]==0 && path[0]=='\\') return Cur_Clust;
else
{
while(path[i]!=0)
{
if(path[i]=='\\')
{
for(;counter<8;counter++)
{
name[counter]=' ';
}
name[counter]=0;
counter=0;
do
{
sec_temp=(SOC(Cur_Clust));
for(iSec=sec_temp;iSec<sec_temp+pArg->SectorsPerClust;iSec++)
{
FAT32_ReadSector(iSec,FAT32_Buffer);
for(iDir=0;iDir<pArg->BytesPerSector;iDir+=sizeof(struct direntry))
{
pDir=((struct direntry *)(FAT32_Buffer+iDir));
if(Compare_Dir_Name(pDir->deName,name))
{
flag=1;
Cur_Clust=LE2BE(pDir->deLowCluster,2)+LE2BE(pDir->deHighClust,2)*65536;
iDir=pArg->BytesPerSector;
iSec=sec_temp+pArg->SectorsPerClust;
}
}
}
Old_Clust=Cur_Clust;
}while(!flag && (Cur_Clust=FAT32_GetNextCluster(Cur_Clust))!=0x0fffffff);
if(!flag)
{
temp_dir_cluster=Old_Clust;
strcpy(temp_dir_name,name);
flag=0;
return 0;
}
flag=0;
}
else
{
name[counter++]=(L2U(path[i]));
}
i++;
}
}
name[counter]=0;
flag=1;
temp_dir_cluster=Cur_Clust;
strcpy(temp_dir_name,name);
return Cur_Clust;
}
/**************************************************************************
- 功能描述:打開一個文件(支持文件名通配,如 A*.txt 或 *.*)
- 隸屬模塊:FAT文件系統模塊
- 函數屬性:外部,使用戶使用
- 參數說明:pfi: FileInfoStruct類型的結構體指針,用來裝載文件的參數信息
比如文件的大小、文件的名稱、文件的開始簇等等,以備后面使用
filepath: 文件的路徑,支持任意層目錄 比如
"\\dir1\\dir2\\dir3\\....\\test.txt"
item:在文件名中有通配符*或?的情況下,實現與之匹配的文件并非
一個,item就是打開的文件的項數,比如符合通配條件的文件有6個,
如果item=3,那么此函數就會打開這6個文件中按順序排號為3的那個
文件(item編號從0開始)
- 返回說明:0:成功 1:文件不存在 2:目錄不存在
- 注:打開文件不成功有很多原因,比如文件不存在、文件的某一級目錄不存在
通配情況下滿足條件的文件項數小于item的值等等
通常情況下,文件名中沒有通配符,item的值我們取0就可以了
**************************************************************************/
UINT8 FAT32_Open_File(struct FileInfoStruct *pfi,INT8 *filepath,unsigned long item)
{
UINT32 Cur_Clust,sec_temp,iSec,iFile,iItem=0;
UINT8 flag=0,index=0,i=0;
struct direntry *pFile;
INT8 temp_file_name[13];
while(filepath[i]!=0)
{
if(filepath[i]=='\\') index=i;
i++;
}
if(Cur_Clust=FAT32_Enter_Dir(filepath))
{
Str2Up(temp_dir_name);
do
{
sec_temp=SOC(Cur_Clust);
for(iSec=sec_temp;iSec<sec_temp+pArg->SectorsPerClust;iSec++)
{
FAT32_ReadSector(iSec,FAT32_Buffer);
for(iFile=0;iFile<pArg->BytesPerSector;iFile+=sizeof(struct direntry))
{
pFile=((struct direntry *)(FAT32_Buffer+iFile));
FAT32_toFileName(pFile->deName,temp_file_name);
if(FilenameMatch(temp_dir_name,temp_file_name) && pFile->deName[0]!=0xe5 && pFile->deAttributes&0x20) //匹配文件名
{
if(item==iItem)
{
flag=1;
Cur_Clust=LE2BE(pFile->deLowCluster,2)+LE2BE(pFile->deHighClust,2)*65536;
pfi->FileSize=LE2BE(pFile->deFileSize,4);
strcpy(pfi->FileName,temp_file_name);
pfi->FileStartCluster=LE2BE(pFile->deLowCluster,2)+LE2BE(pFile->deHighClust,2)*65536;
pfi->FileCurCluster=pfi->FileStartCluster;
pfi->FileCurSector=SOC(pfi->FileStartCluster);
pfi->FileCurPos=0;
pfi->FileCurOffset=0;
pfi->Rec_Sec=iSec;
pfi->nRec=iFile;
pfi->FileAttr=pFile->deAttributes;
sec_temp=LE2BE(pFile->deCTime,2);
(pfi->FileCreateTime).sec=(sec_temp&0x001f)*2;
(pfi->FileCreateTime).min=((sec_temp>>5)&0x003f);
(pfi->FileCreateTime).hour=((sec_temp>>11)&0x001f);
sec_temp=LE2BE(pFile->deCDate,2);
(pfi->FileCreateDate).day=((sec_temp)&0x001f);
(pfi->FileCreateDate).month=((sec_temp>>5)&0x000f);
(pfi->FileCreateDate).year=((sec_temp>>9)&0x007f)+1980;
sec_temp=LE2BE(pFile->deMTime,2);
(pfi->FileMTime).sec=(sec_temp&0x001f)*2;
(pfi->FileMTime).min=((sec_temp>>5)&0x003f);
(pfi->FileMTime).hour=((sec_temp>>11)&0x001f);
sec_temp=LE2BE(pFile->deMDate,2);
(pfi->FileMDate).day=((sec_temp)&0x001f);
(pfi->FileMDate).month=((sec_temp>>5)&0x000f);
(pfi->FileMDate).year=((sec_temp>>9)&0x007f)+1980;
sec_temp=LE2BE(pFile->deADate,2);
(pfi->FileADate).day=((sec_temp)&0x001f);
(pfi->FileADate).month=((sec_temp>>5)&0x000f);
(pfi->FileADate).year=((sec_temp>>9)&0x007f)+1980;
iFile=pArg->BytesPerSector;
iSec=sec_temp+pArg->SectorsPerClust;
}
else
{
iItem++;
}
}
}
}
}while(!flag && (Cur_Clust=FAT32_GetNextCluster(Cur_Clust))!=0x0fffffff);
if(!flag)
{
return 1;
}
return 0;
}
else
{
return 2;
}
}
/**************************************************************************
- 功能描述:文件定位
- 隸屬模塊:FAT文件系統模塊
- 函數屬性:外部,使用戶使用
- 參數說明:pfi:FileInfoStruct類型的結構體指針,用于裝載文件參數信息,文件
定位后,pfi所指向的結構體中的相關參數就被更新了,比如文件的當前
扇區,文件當前扇區中的位置,文件的當前偏移量等等,以備后面使用
offset:要定位的偏移量,如果offset大于文件的大小,則定位到文件的
末尾
- 返回說明:文件定位成功返回0,否則為1
- 注:此函數被下面的FAT32_Read_File調用,用于實現從指定位置讀取數據,不建議
用戶直接調用些函數
**************************************************************************/
UINT8 FAT32_Seek_File(struct FileInfoStruct *pfi,UINT32 offset)
{
UINT32 i,temp;
if(offset<=pfi->FileSize)
{
if(offset==pfi->FileCurOffset)
{
pfi->FileCurPos%=pArg->BytesPerSector;
return 1;
}
if(offset<pfi->FileCurOffset)
{
pfi->FileCurCluster=pfi->FileStartCluster;
pfi->FileCurSector=SOC(pfi->FileCurCluster);
pfi->FileCurPos=0;
pfi->FileCurOffset=0;
}
if((offset-pfi->FileCurOffset)>=(pArg->BytesPerSector-pfi->FileCurPos)) //目標偏移量與文件當前偏移量所差的字節數不小于文件在當前扇區中的位置到扇區末尾的字節數
{
pfi->FileCurOffset+=(pArg->BytesPerSector-pfi->FileCurPos);
pfi->FileCurPos=0;
if(pfi->FileCurSector-SOC(pfi->FileCurCluster)==(pArg->SectorsPerClust-1))
{
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
pfi->FileCurSector=SOC(pfi->FileCurCluster);
}
else
{
pfi->FileCurSector++;
}
}
else
{
pfi->FileCurPos=(pfi->FileCurPos+offset-pfi->FileCurOffset)%pArg->BytesPerSector;
pfi->FileCurOffset=offset;
return 1;
}
temp=SOC(pfi->FileCurCluster);
if((offset-(pfi->FileCurOffset))/pArg->BytesPerSector+(pfi->FileCurSector-temp)>(pArg->SectorsPerClust-1))
{
pfi->FileCurOffset+=(((pArg->SectorsPerClust)-(pfi->FileCurSector-(SOC(pfi->FileCurCluster))))*pArg->BytesPerSector);
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
pfi->FileCurSector=SOC(pfi->FileCurCluster);
pfi->FileCurPos=0;
}
else
{
pfi->FileCurSector+=(offset-pfi->FileCurOffset)/pArg->BytesPerSector;
pfi->FileCurPos=(offset-pfi->FileCurOffset)%pArg->BytesPerSector;
pfi->FileCurOffset=offset;
return 1;
}
temp=(offset-pfi->FileCurOffset)/(pArg->BytesPerSector*pArg->SectorsPerClust);
for(i=0;i<temp;i++)
{
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
}
pfi->FileCurOffset+=(temp*(pArg->BytesPerSector*pArg->SectorsPerClust));
pfi->FileCurSector=(SOC(pfi->FileCurCluster))+(offset-pfi->FileCurOffset)/pArg->BytesPerSector;
pfi->FileCurPos=((offset-pfi->FileCurOffset))%pArg->BytesPerSector;
pfi->FileCurOffset=offset;
}
else
{
return 1;
}
return 0;
}
/**************************************************************************
- 功能描述:從文件的某一個位置處,讀取一定長度的數據,放入數據緩沖區中
- 隸屬模塊:FAT文件系統模塊
- 函數屬性:外部,使用戶使用
- 參數說明:pfi:FileInfoStruct類型的結構體指針,用于裝載文件參數信息,文件
讀取的過程中,此結構體中的相關參數會更新,比如文件的當前偏移量、
文件的當前扇區,文件的當前簇等等
offset:要定位的偏移量,要小于文件的大小
len:要讀取的數據的長度,如果len+offset大于文件的大小,則實際讀
取的數據量是從offset開始到文件結束
pbuf:數據緩沖區
- 返回說明:讀取到的實際的數據長度,如果讀取失敗,比如指定的偏移量大于了文件
大小,則返回0
- 注:在讀取一個文件的數據前,必須先將該文件用FAT32_Open_File打開
**************************************************************************/
UINT32 FAT32_Read_File(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,UINT8 *pbuf)
{
UINT32 i,j,k,temp;
UINT32 counter=0;
if(offset<pfi->FileSize)
{
if(offset+len>pfi->FileSize) len=pfi->FileSize-offset;
FAT32_Seek_File(pfi,offset);
FAT32_ReadSector(pfi->FileCurSector,FAT32_Buffer);
for(i=pfi->FileCurPos;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=FAT32_Buffer[i];
counter++;
pfi->FileCurPos++;
pfi->FileCurOffset++;
}
if(pfi->FileCurSector-(SOC(pfi->FileCurCluster))!=(pArg->SectorsPerClust-1))
{
for(j=pfi->FileCurSector+1;j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
{
FAT32_ReadSector(j,FAT32_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=FAT32_Buffer[i];
counter++;
pfi->FileCurPos++;
pfi->FileCurOffset++;
}
}
}
temp=(len-counter)/(pArg->BytesPerSector*pArg->SectorsPerClust);
for(k=0;k<temp;k++)
{
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
for(j=(SOC(pfi->FileCurCluster));j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
{
FAT32_ReadSector(j,FAT32_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=FAT32_Buffer[i];
counter++;
pfi->FileCurOffset++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
}
}
}
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
temp=(SOC(pfi->FileCurCluster))+((len-counter)/pArg->BytesPerSector);
pfi->FileCurSector=(SOC(pfi->FileCurCluster));
for(j=(SOC(pfi->FileCurCluster));j<temp;j++)
{
FAT32_ReadSector(j,FAT32_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=FAT32_Buffer[i];
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
pfi->FileCurSector=j;
FAT32_ReadSector(pfi->FileCurSector,FAT32_Buffer);
temp=len-counter;
for(i=0;i<temp;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=FAT32_Buffer[i];
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -