<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
四、添加命令fcopy、fpath。
1、目的
(1)fcopy:复制功能,原文件保留,新位置建立文件。
(2)fpath:在支持相对路径的情况下,显示当前磁盘的当前目录。
2、fcopy命令的实现
(1)复制命令的实现思路
首先要打开两个文件,原文件以可读FA_READ的方式打开,新文件以 FA_CREATE_NEW和FA_WRITE的方式打开。
然后建立一个循环,每次从原文件读出一个扇区的数据,写入新文件。然后检查原文件 结束标志,已到结尾,则跳出循环。
关闭两个文件,更新文件信息。
(2)代码实现
res = f_open ( &FileOld, (const char *)argv[1], FA_READ );
res = f_open ( &FileNew, (const char *)argv[2], FA_CREATE_NEW | FA_WRITE );
for ( ; ; ){
res = f_read ( &FileOld, (void*)FileBuf, 512, &ByteRead );
res = f_write ( &FileNew, ( const void *)FileBuf, ByteRead, &ByteWrite );
if (FileOld.fptr== FileOld.fsize) )break;
}
f_close (&FileOld);
f_close (&FileNew);
编译,下载,功能正确。
3、fpath命令的实现
(1)这个命令实现起来稍微有些难度
首先要获取当前磁盘 和 当前磁盘的当前目录所在簇,也就是FatFs[Drive]->cdir,如果为0,表明是在磁盘根目录,显示0:或者1:。如果该簇号等于根目录所在簇号,当前目录也是在跟目录。
如果不是在根目录,那就要逐层往上搜索了。根据f_opendir (DIR,..目录)可以回溯到上层目录,DIR结构体得到了上层目录(X+1)的起始簇号,目录项指针指向第0项。用f_readdir()逐步读出目录项属性,得到FILINFO结构体。如果其簇号 等于 文件系统的当前搜索簇号,则其名称就是所要得到的本层目录名。如果是根目录下则为 0:/X目录名。
当前搜索簇号设为(X+1)的起始簇号。再次调用f_opendir( DIR,..目录),此次得到(X+2)的起始簇号,判断是否根目录。查找当期搜索簇号在(X+2)目录层中对应的目录项,并获取X+1层的目录名。如果是在根目录,则为0:/X+1目录名/X目录名。
循环直到到达根目录跳出搜索。
目录名缓冲区的处理方法。定义总长度为100字节。Path[99]=0;初始化时先让指针指向Path【99】。
得到一个目录,向前移动名称那么长,复制名称。再往前移动1,添加’/’标志。如果是根目录添加’:’,往前移动1,在添加‘驱动号’,然后可以显示整个字符串。
(2)代码实现
for ( ; ; ){
if ( CurClust == 0 || CurClust == CurFileSys->dirbase ) {
PathPtr--;
*PathPtr--=':'; /
*PathPtr = CurDrive+'0'; //如果当前簇号对应根目录。
break; }
res = f_opendir ( &DirInf, ".." ); //第一次执行时,DIR结构体的开始簇号变为X+1层目录的簇号 //第二次时,变为X+2层目录的簇号。
if ( res!= FR_OK ) break;
do {
res = f_readdir ( &DirInf, &FileAttrib );
TempClust = FileAttrib.sclust;
if ( TempClust == CurClust ) break; //如果该目录项的簇号等于当前搜索簇号,它的名称就是当前需要的目录名
} while( res == FR_OK );
if ( res!= FR_OK ) break;
DirLen= Str_Length ( (const char*)FileAttrib.fname ); //这里要得到字符串的长度。
PathPtr -= DirLen; //文件指针往后退目录名长度
mem_cpy ( (void *)PathPtr, ( const void*)FileAttrib.fname, DirLen);
PathPtr--;
*PathPtr='/'; //添加文件间隔/符号。
CurClust = DirInf.sclust; //当前搜索簇号跟着上移。
}
Uart_PutString( PathPtr); //这是显示的当前目录。
Uart_PutString( "\r\n");
编译,下载,显示两层目录是正确的。但是目录一旦到第三层,就进入死循环。还要接着调试。
(3)调试
经调试发现res = f_opendir ( &DirInf, ".." )调用后,并不能每次都自动回溯到上一层目录。
所以改为:f_opendir ( &DirInf, (const char*)ddPtr),ddPtr初始化成“..”,然后每循环一次,前面加上”../”,第二次变为 ”../..”,第三次变为“../../.. “,这样目录不断回溯。
以下是该命令实现的截图。
文章评论(0条评论)
登录后参与讨论