基于c语言的文件系统FAT16操作源代码
更新时间:2024-01-19 06:13:01 阅读量: 教育文库 文档下载
- c语言缓冲文件系统推荐度:
- 相关推荐
文件: FAT.H
//微控设计网原创 www.Microcontrol.cn 作者: debug版主 typedef unsigned char uint8; typedef unsigned int uint16; typedef unsigned long uint32;
#pragma pack(1)
typedef struct {
uint8 BS_jmpBoot[3]; uint8 BS_OEMName[8]; uint16 BPB_BytesPerSec; uint8 BPB_SecPerClus; uint16 BPB_RsvdSecCnt; uint8 BPB_NumFATs; uint16 BPB_RootEntCnt; uint16 BPB_TotSec16; uint8 BPB_Media; uint16 BPB_FATSz16; uint16 BPB_SecPerTrk; uint16 BPB_NumHeads; uint32 BPB_HiddSec; uint32 BPB_TotSec32; uint8 BS_DrvNum; uint8 BS_Reservedl; uint8 BS_BootSig; uint32 BS_VolID; uint8 BS_VolLab[11]; uint8 BS_FilSysType[8]; uint8 ExecutableCode[448]; uint8 ExecutableMarker[2]; } FAT_BPB; typedef struct {
uint8 NAME[8]; uint8 TYPE[3]; } FILE_NAME; typedef struct {
uint16 Start; uint32 Size; } FILE_POSIT; typedef struct {
1
FILE_NAME FileName; uint8 FileAttrib; uint8 UnUsed[10];
uint8 FileUpdateTime[2]; uint8 FileUpdateData[2]; FILE_POSIT FilePosit; } DIR;
typedef struct {
uint16 ClusID; uint16 SecOfClus; uint16 ByteOfSec; } DATA_POSIT;
#pragma pack()
//************************************************************************** //读一个扇区
void ReadBlock(uint32 LBA);
//************************************************************************** //写一个扇区
void WriteBlock(uint32 LBA);
//************************************************************************** void CopyBytes(void* S, void* D, uint16 size);
//************************************************************************** uint8 IsEqual(void* A, void* B, uint8 Size);
//************************************************************************* void EmptyBytes(void* D, uint16 size);
//************************************************************************** //读取BPB数据结构 void ReadBPB(void);
//*************************************************************************** //获取根目录开始扇区号 uint32 DirStartSec(void);
//**************************************************************************** //获取数据区开始扇区号 uint32 DataStartSec(void);
//*************************************************************************** //目录项占用的扇区数
uint16 GetDirSecCount(void);
//**************************************************************************** //获取一个簇的开始扇区
uint32 ClusConvLBA(uint16 ClusID);
//**************************************************************************** //读取文件分配表的指定项
uint16 ReadFAT(uint16 Index);
2
//**************************************************************************** //写文件分配表的指定项
void WriteFAT(uint16 Index, uint16 Value);
//************************************************************************** //获取根目录中可以使用的一项 uint16 GetEmptyDIR(void);
//**************************************************************************** //获得和文件名对应的目录项
uint8 GetFileID(uint8 Name[11], DIR* ID);
//*************************************************************************** //获取一个空的FAT项 uint16 GetNextFAT(void);
//**************************************************************************** //读取根目录的指定项
void ReadDIR(uint16 Index, DIR* Value);
//**************************************************************************** //写根目录的指定项
void WriteDIR(uint16 Index, DIR* Value);
//**************************************************************************** //创建一个空文件
void CreateFile(uint8* FileName[11], uint32 Size);
//************************************************************************ //复制文件分配表,使其和备份一致 void CopyFAT(void);
//**************************************************************************** //操作文件的数据
void OperateFile(uint8 Write ,uint8 Name[11], uint32 Start, uint32 Length, void* Data); //-------------------------------------------------------------------------------
3
文件:FAT.C
//微控设计网原创 www.Microcontrol.cn 作者: debug版主 #include
uint8 BUFFER[512];
uint16 BPB_BytesPerSec; uint8 BPB_SecPerClus; uint16 BPB_RsvdSecCnt; uint8 BPB_NumFATs; uint16 BPB_RootEntCnt; uint16 BPB_TotSec16; uint16 BPB_FATSz16; uint32 BPB_HiddSec;
//******************************************************************************** //读一个扇区
void ReadBlock(uint32 LBA)
//******************************************************************************** {
return; }
//******************************************************************************** //写一个扇区
void WriteBlock(uint32 LBA)
//******************************************************************************** {
return; }
//******************************************************************************** void CopyBytes(void* S, void* D, uint16 size)
//******************************************************************************** {
uint8 *s = S, *d = D; uint16 i;
for(i = 0; i < size; i++) *d++ = *s++; }
//********************************************************************************* uint8 IsEqual(void* A, void* B, uint8 Size)
//**********************************************************************************
4
{
uint8 i, *a = A, *b = B; for(i = 0; i < Size; i++) if(a[i] != b[i]) return 0; return 1; }
//*********************************************************************************** void EmptyBytes(void* D, uint16 size)
//*********************************************************************************** {
uint16 i;
uint8* data = (uint8*)D; for(i = 0; i < size; i++) {
*data++ = 0; } }
//********************************************************************************** //读取BPB数据结构 void ReadBPB(void)
//*********************************************************************************** {
FAT_BPB* BPB = (FAT_BPB*)BUFFER; ReadBlock(0);
//获取参数
BPB_BytesPerSec = BPB->BPB_BytesPerSec; BPB_SecPerClus = BPB->BPB_SecPerClus; BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt; BPB_NumFATs = BPB->BPB_NumFATs;
BPB_RootEntCnt = BPB->BPB_RootEntCnt; BPB_TotSec16 = BPB->BPB_TotSec16; BPB_FATSz16 = BPB->BPB_FATSz16; BPB_HiddSec = BPB->BPB_HiddSec; }
//************************************************************************************* //获取根目录开始扇区号 uint32 DirStartSec(void)
//************************************************************************************* {
return BPB_RsvdSecCnt + BPB_NumFATs * BPB_FATSz16;
5
}
//************************************************************************************ //获取数据区开始扇区号 uint32 DataStartSec(void)
//************************************************************************************ {
return (uint32)(DirStartSec() + BPB_RootEntCnt * 32 / BPB_BytesPerSec); }
//************************************************************************************ //目录项占用的扇区数
uint16 GetDirSecCount(void)
//************************************************************************************ {
return BPB_RootEntCnt * 32 / 512; }
//************************************************************************************ //获取一个簇的开始扇区
uint32 ClusConvLBA(uint16 ClusID)
//************************************************************************************* {
return DataStartSec() + BPB_SecPerClus * (ClusID - 2); }
//************************************************************************************* //读取文件分配表的指定项 uint16 ReadFAT(uint16 Index)
//*********************************************************************************** {
uint16 *RAM = (uint16*)BUFFER;
ReadBlock(BPB_RsvdSecCnt + Index / 256); return RAM[Index % 256]; }
//*********************************************************************************** //写文件分配表的指定项
void WriteFAT(uint16 Index, uint16 Value)
//*********************************************************************************** {
uint16 *RAM = (uint16*)BUFFER; uint32 SecID;
SecID = BPB_RsvdSecCnt + Index / 256; ReadBlock(SecID);
RAM[Index % 256] = Value;
6
WriteBlock(SecID); }
//*********************************************************************************** //获取根目录中可以使用的一项 uint16 GetEmptyDIR()
//*********************************************************************************** {
uint16 DirSecCut, DirStart, i, m, ID = 0; DirSecCut = GetDirSecCount(); DirStart = DirStartSec();
for(i = 0; i < DirSecCut; i++) {
ReadBlock(DirStart + i); for(m = 0; m < 16; m++) {
if((BUFFER[m * 32] == 0) || (BUFFER[m * 32] == 0xe5)) return ID; else
ID++; } }
return ID; }
//************************************************************************************ //获得和文件名对应的目录项
uint8 GetFileID(uint8 Name[11], DIR* ID)
//************************************************************************************ {
uint16 DirSecCut, DirStart, i, m; DirSecCut = GetDirSecCount(); DirStart = DirStartSec();
for(i = 0; i < DirSecCut; i++) {
ReadBlock(DirStart + i); for(m = 0; m <16; m++) {
if(IsEqual(Name, &((DIR*)&BUFFER[m * 32])->FileName, 11)) {
*ID = *((DIR*)&BUFFER[m * 32]);
return 1; //找到对应的目录项,返回1. } } }
return 0; //没有找到对应的目录项,返回0.
7
}
//************************************************************************************** //获取一个空的FAT项 uint16 GetNextFAT(void)
//************************************************=************************************* {
uint16 FAT_Count, i;
FAT_Count = BPB_FATSz16 * 256; //FAT表总项数 for(i = 0; i < FAT_Count; i++) {
if(ReadFAT(i) == 0) return i; }
return 0; }
//************************************************************************************** //读取根目录的指定项
void ReadDIR(uint16 Index, DIR* Value)
//************************************************************************************ {
uint32 DirStart = DirStartSec(); ReadBlock(DirStart + Index / 16);
CopyBytes(&BUFFER[(Index % 16) * 32], Value, 32); }
//************************************************************************************* //写根目录的指定项
void WriteDIR(uint16 Index, DIR* Value)
//************************************************************************************* {
uint32 LBA = DirStartSec() + Index / 16; ReadBlock(LBA);
CopyBytes(Value, &BUFFER[(Index % 16) * 32], 32); WriteBlock(LBA); }
//************************************************************************************* //创建一个空文件
void CreateFile(uint8* FileName[11], uint32 Size)
//************************************************************************************* {
uint16 ClusID, ClusNum, ClusNext, i; DIR FileDir;
ClusNum = Size / (BPB_SecPerClus * 512) + 1; EmptyBytes(&FileDir, sizeof(DIR));
8
CopyBytes(FileName, &FileDir.FileName, 11); FileDir.FilePosit.Size = Size;
FileDir.FilePosit.Start = GetNextFAT(); ClusID = FileDir.FilePosit.Start; for(i = 0; i < ClusNum - 1; i++) {
WriteFAT(ClusID, 0xffff); ClusNext = GetNextFAT(); WriteFAT(ClusID, ClusNext); ClusID = ClusNext; }
WriteFAT(ClusID, 0xffff);
WriteDIR(GetEmptyDIR(), &FileDir); }
//************************************************************************************ //复制文件分配表,使其和备份一致 void CopyFAT(void)
//************************************************************************************ {
uint16 FATSz16, RsvdSecCnt, i; FATSz16 = BPB_FATSz16;
RsvdSecCnt = BPB_RsvdSecCnt; for(i = 0; i < FATSz16; i++) {
ReadBlock(RsvdSecCnt + i);
WriteBlock(RsvdSecCnt + FATSz16 + i); } }
//************************************************************************************* //操作文件的数据
void OperateFile(uint8 Write ,uint8 Name[11], uint32 Start, uint32 Length, void* Data) //************************************************************************************* {
uint8 *data = Data;
uint16 BytePerClus, SecPerClus, ClusNum, ClusID, m; uint32 LBA, i; DIR FileDir;
SecPerClus = BPB_SecPerClus;
BytePerClus = BPB_SecPerClus * 512; // 每簇的字节数 GetFileID(Name, &FileDir);
//计算开始位置所在簇的簇号 ClusNum = Start / BytePerClus; ClusID = FileDir.FilePosit.Start;
9
for(i = 0; i < ClusNum; i++) ClusID = ReadFAT(ClusID);
//计算开始位置所在扇区簇内偏移 i = (Start % BytePerClus) / 512;
//计算开始位置扇区内偏移
m = (Start % BytePerClus) % 512;
LBA = ClusConvLBA(ClusID) + m;
if(Write)
ReadBlock(LBA); else
ReadBlock(LBA++);
goto Start;
while(1) {
ClusID = ReadFAT(ClusID); //下一簇簇号 LBA = ClusConvLBA(ClusID);
for(i = 0; i < SecPerClus; i++) {
if(Write)
ReadBlock(LBA); else
ReadBlock(LBA++);
for(m = 0; m < 512; m++) { Start:
if(Write)
BUFFER[m] = *data++; else
*data++ = BUFFER[m];
//如果读取完成就退出 if(--Length == 0) {
if(Write)
WriteBlock(LBA); //回写扇区 return; } }
if(Write)
10
WriteBlock(LBA++); //回写扇区,指针下移 } } }
//--------------------------------------------------------------------------------------
11
正在阅读:
基于c语言的文件系统FAT16操作源代码01-19
读《为你自己工作》有感范文03-24
1思修选择题库(带答案)12-06
委托支付协议(贸易融资)09-03
小学道德与法治_2.《我们生活离不开他们》教学设计学情分析教材04-08
土木工程框架结构毕业设计全套论文06-04
2019年中国疲劳驾驶预警系统现状调研及市场前景预测(目录)10-08
九型人格与领导力08-14
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 源代码
- 基于
- 语言
- 操作
- 文件
- 系统
- FAT16