下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、、读文件流程。1程序结构res = f_moun t(0, & fs);res = f_ope n(&file, data.txt, FA_OPEN_EXISTING | FA_READ); while if(fgets(data, sizeof(data), &file)=NULL) break; prin ts(data);f_close(&file);总共四个与文件系统相关的函数,下面就沿着函数执行路径去探索一下。2、f_mount(0, &fs)的执行参数0是卷号,就像电脑上的 CDE盘等。fs是一个未初始化的一个文件系统对象,其定义在此:FATFS fs=这个函数好像就做了两个个事,
2、使全局文件系统指针FatFS指向fs对象,并使fs.fstype=0。3、f_open(&file, data.txt, FA_OPEN_EXISTING | FA_READ) 的执行FA_OPEN_EXISTING |参数&file是提供一个文件对象指针,打开文件过程中获得的一些信息都填入这个结构体。FA_READ表示要打开和读取相应的文件。源程序如下:FRESULT f_ope n (/* fp就指向传入的对象 file */*path 指向 data.txt 的地址 */* Access mode and file ope n mode flags */FIL *fp, const ch
3、ar *path, BYTE mode)DIR dj;目录对象 BYTE *dir;目录项指针char fn8+3+1; 8.3 文件名。 改为 NAMEBUF(sfn, Ifn)。/程序开头定义了这么三个变量,007c版本中由于支持长文件名,最好一个fp-fs = NULL;每个文件对象都指向具体的文件系统,这里先清0auto_mou nt(&path, & dj.fs, (BYTE)(mode); 这个函数看来很关键了。旧版的函数没有中间这个参数。Path本来就是一个指针,&path就是一个指向指针的指针,&dj.fs因为dj对象还未设置,这个指针传入应该是供auto_mount函数设置的
4、。4、auto_mount(&path, &dj.fs, (BYTE)(mode)的执行先分析旧版的:FRESULT auto_m ount ( const char *path, BYTE chk_wp/* FR_OK(0): successful, !=0: any error occured */* Poi nter to poin ter to the path n ame (drive nu mber) */* !=0: Check media write protect ion for write access)DWORD bootsect, fatsize, totalsect,
5、 maxclust;con st char *p = *path; /指针p现在就指向文件名字符串了。FATFS *fs;memset(fs, 0, sizeof(FATFS);/* 将全局文件系统结构清 0 */stat = disk_i nitialize(0);/*磁盘初始化程序,在这里调用的 */fmt = check_fs(bootsect = 0);/* Check sector 0 as an SFD format */这里主要是调用了 check_fs(bootsect = 0函数检测是否存在 FAT文件系统。下面是源代码:BYTE check_fs ( /* 0:The FA
6、T boot record, 1:Valid boot record but not an FAT, 2:Not a boot record or error */DWORD sect /* Sector# to check if it is an FAT boot record or not */) FATFS *fs = FatFs;if (disk_read(0, fs-w in, sect, 1) != RES_OK) /* Load boot record */return 2;if (LD_WORD(&fs-wi nBS_55AA) != 0xAA55)/*Check record
7、 sig nature */return 2;if (!memcmp(&fs-wi nBS_FilSysType, FAT, 3)/* Check FAT sig nature */return 0;if (!memcmp(&fs-wi nBS_FilSysType32, FAT32, 5) & !(fs-wi nBPB_ExtFlags & 0x80)return 0;return 1;这个函数的主要操作是:将磁盘的0扇区读入fs-win【】扇区缓冲。并对其中的特殊位置进行检验。如果读入错误或者末尾不是55AA,返回2。如果确实是 FAT文件系统返回0。如果返回1可能是主引导扇区,继续从分区
8、引导扇 区读取。auto_mount继续往下执行:fatsize = LD_DWORD(&fs-w in BPB_FATSz32);fs-sects_fat = (CLUST)fatsize; /每个 FAT表的扇区数目fs-n_fats = fs-winBPB_NumFATs;/* FAT 表的个数 */fatsize *= fs-n _fats;/* (Number of sectors in FAT area)*/fs-fatbase = bootsect + LD_WORD(&fs-winBPB_RsvdSecCnt);/* FAT start sector (Iba)*/FAT表开始
9、于开始扇区+保留扇区。fs-csize = fs-winBPB_SecPerClus;/* 每个簇的扇区数目*/fs-n_rootdir = LD_WORD(&fs-winBPB_RootEntCnt);/* Nmuber of root directoryen tries */totalsect = LD_DWORD(&fs-wi n BPB_TotSec32);fs-max_clust = maxclust;fmt = FS_FAT32;if (fmt = FS_FAT32)fs-dirbase = LD_DWORD(&fs-wi nBPB_RootClus);fs-database =
10、fs-fatbase + fatsize + fs-n _rootdir / 16;/* Data start sector (lba)fs-free_clust = (CLUST)0xFFFFFFFF;以上代码主要是根据引导扇区里的数据,填充文件系统对象结构体的信息:包括FAT表大小、数目、根目录区起始地址、数据区起始扇区、文件系统类型等等。后面还有一些代码,也是做同样工作的,这里就不再叙述了。函数下面回到f_open继续执行。Auto_mount函数早期有个转折,如果文件系统类型已经定义,则直接返回,后续代码不会执行。5、f_open()执行完 auto_mount()后下一个函数:tra
11、ce_path(&dj, fn, path, & dir); /* Trace the file path */这个函数里面只有path指向文件路径,其它三个都是未经初始化的指针,应该都是在这个函数里面进行设置。Dj是目录结构体,fn是8.3文件名数组,dir是指向fs扇区缓冲里当前文件目录项的指针。从函数名称和参数可以推断出它的主要功能是将文件名从路径中提取出来,并转变成从标准8.3格式,同时找到文件所在目录,并将目录扇区读入文件系统缓冲区,依据文件目录项的信息填充dj结构体。新的007c代码中已经改成了 follow_path (); 以下是源代码:FRESULT trace_path (
12、DIR *dj, char *fn,co nst char *path, BYTE *dir )dj-fs = fs;clust = fs-dirbase;if (fs-fs_type = FS_FAT32) dj-clust = dj-sclust = clust; 目录项的当前簇和开始簇都指向根目录区dj-sect = clust2sect(clust);从簇号得到相应的扇区。dj-i ndex = 0; /目录索引项先初始化为 0for (;) ds = make_dirfile(&path, fn);/* Get a paragraph into fn */make_dirfile(&
13、path, fn)功能是获得文件名,跟进源代码看一看:有些地方还不是太清晰,但大概意思是抽取目录。有效格式如:/dirl/dirll/filel.txt等,执行该函数后fn应该=dirl*.*,”性质是目录。move_window(dj-sect) ; /这个函数是将对应簇读到文件系统缓冲区。dptr = & fs-wi n (dj-i ndex & 15) * 32;这是一个目录项的指针。memcmp(&dptrDIR_Name, fn, 8+3); 将文件名或目录名与当前目录项比较,看是不是需要打开的文件或者目录。如果不是,则取出下一个目录项:next_dir_entry(dj);然后进行
14、循环。没有找到的。外层循环继续把目录剥离,往下寻找。最终找到对应的文件。trace_path()函数返回以后,f_open ()函数主要根据 trace_path所得到的信息填充file文件结构体。比如:fp-dir_sect = dj.fs-winsect;/* 指向目录项所在扇区*/fp-dir_ptr = dir; 指向扇区中对应目录项的指针fp-flag = mode;/* File access mode */fp-org_clust =/* File start cluster */(DWORD )L D_WORD(&dirDIR_FstClusHI) fsize = LD_DWO
15、RD(&dirDIR_FileSize);/* File size */fp-fptr = 0; fp-csect = 255;/* 文件读写指针为 0 */fp-fs = dj.fs; fp-id = dj.fs-id;/* Owner file system object of the file */f_open ()到此执行结束。6、fgets(data, sizeof(data), &file)的执行该函数的主要参数是数据缓冲区data,和文件结构描述符 file。跟进源代码:while (i fsize - fp-fptr; /文件大小减去当前位置,得到剩下的字节数。if(btr r
16、emai n) btr = (UINT)rema in;/如果要读的字节数大于剩余字节数,则调整。举个例子,从文件头开始读 5128个字节,共占据11个扇区。一簇以8个扇区计算。for ( ; btr;/* Repeat un til all data tran sferred */rbuff += rent, fp-fptr += rent, *br += rent, btr -= rent)if (fp-fptr % 512U) = 0) /*读初始指针位于扇区位于边界*/sect = elust2seet(fp-eurr_elust) + fp-eseet;/* 簇的第一个扇区 */ e
17、e = btr / 512U;/* ee=10表示多于一个扇区,*/if (ee) /* Read maximum contiguous seetors direetly*/if (fp-eseet + ee fp-fs-esize) /* 多于一个簇 */ee = fp-fs-esize - fp-eseet; 暂时先读一个簇。if (disk_read(O, rbuff, seet, (BYTE)ee) != RES_OK) goto fr_error;fp-eseet += (BYTE)ee; /* 移动到下一个簇 */ rent = 512U * ee;/* Number of byt
18、es tran sferred */con ti nue;/*移动到下一簇 */第二次读时,要执行下面语句:第二次要读两个扇区if (fp-eseet = fp-fs-esize) elust = (fp-fptr = 0)/* On the top of the file? */fp-org_elust : get_eluster(fp-eurr_elust); if (elust = fp-fs-max_clust) goto fr_error;fp-eurr_elust = elust; fp-eseet = 0;/*更新当前簇*/*簇内扇区号变为0 */第二次读时额外执行的语句。fp-
19、csect+;/*这个在第三次读时也会执行*/往下语句也会在第三次读时执行。sect = clust2sect(fp-curr_clust) + fp-eseet - 1;/*如果文件读写指针不在扇区边界,为了读到数据,必须往前走一个扇区*/-if (!move_wi ndow(sect) goto fr_error;/* Move sector wi ndow */rent = 512U - (fp-fptr % 512U);* Get partial sector from sector win dow */if (rent btr) rent = btr;memepy(rbuff, &
20、fp-fs-wi nfp-fptr % 512U, rent);8、f_elose()主要做了两个工作:(1)res = f_syne(fp);将文件的改动写入,同时调用函数syne()将文件系统变化写入文件系统相应信息区域。(2)fp-fs=O,将文件关闭。/二、写文件流程分析1、写文件程序结构。res = f_ope n(&file, 331.txt, FA_CREATE_ALWAYS | FA_WRITE); res = f_write(&file, data, 512, &br);f_close(&file);2、函数 f_open(&file, 331.txt, FA_CREATE_ALW AYS | FA_W
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论