表头文件:#include <ftw.h>
定义函数:int ftw(const char *dir, int (*fn) (const *file, const structstat *sb, int flag), int depth)
函数说明:ftw() 会从参数dir指定的 目录开始,往下一层层地递归式遍历子 目录。ftw()会传三个参数给fn(), 第一个参数*file指向当时所在的目录路径,第二个参数是*sb,为stat结构指针,第三个参数为旗标,有下面几种可能值:
FTW_F 一般文件
FTW_D 目录
FTW_DNR 不可读取的 目录,此 目录以下将不被遍历
FTW_SL 符号连接
FTW_NS 无法取得stat结构数据,有可能是 权限问题
最后一个参数depth代表ftw()在进行遍历 目录时同时打开的文件数。ftw()在遍历时每一层 目录至少需要一个文件描述词,如果遍历时用完了depth所给予的限制数目,整个遍历将因不断地关文件和开文件操作而显得缓慢.
如果要结束ftw()的遍历,fn()只需返回一非零值即可,此值同时也会是ftw()的返回值。否则ftw()会试着走完所有的目录,然后返回0.
返回值:遍历中断则返回fn()函数的返回值,全部遍历则返回0,若有错误发生则返回-1
函数定义: int nftw(const char *dir, int (*fn)(constchar *file, const struct stat *sb, int flag, struct FTW *s), depth,int flags);
说明: nftw()与ftw()很像, 都是从参数dir指定的目录开始, 往下一层层地递归式遍历子目录. 每进入一个目录,便会调用参数*fn定义的函数来处理. nftw()会传四个参数给fn(), 第一个参数*file指向当时所在的目录路径,第二个参数是*sb, 为stat结构指针(结构定义请参考stat()), 第三个参数为旗标, 有以下几种可能:
FTW_F 一般文件
FTW_D 目录
FTW_DNR 不可读取的目录. 此目录以下将不被遍历
FTW_SL 符号连接
FTW_NS 无法取得stat结构数据, 有可能是权限问题
FTW_DP 目录, 而且其子目录都已被遍历过了.
FTW_SLN 符号连接, 但连接不存在文件
fn()的第四个参数是FTW结构, 定义如下:
struct FTW{
int base;
int level;
}
level代表遍历当时的深度, nftw()第三个参数depth代表nftw()在进行遍历目录时可同时打开的文件数.ftw()在遍历时每一层目录至少需要一个文件描述词, 如果遍历时用完了depth所给予的限制数目,整个遍历将因不断地关闭文件和打开文件操作而显得缓慢. nftw()最后一个参数flags用来指定遍历时的动作,可以指定下列的操作或用OR组合:
FTW_CHDIR 在读目录之前用chdir()移到此目录
FTW_DEPTH 执行深度优先搜索. 在遍历此目录前先将所有子目录遍历完
FTW_MOUNT 遍历时不要跨越到其他文件系统
FTW_PHYS 不要遍历符号连接的目录. 预设会遍历符号连接目录
如果要结束ftw()的遍历, fn()只需返回一非零值即可, 此值同时也会是ftw()的返回值, 否则ftw()会试着走完所有的目录,然后返回0. 遍历中断则返回fn()函数的返回值, 全部遍历完则返回0. 如有错误发生则返回-1.
附加说明: 由于ftw()会动态配置内存使用, 请使用正常方式(fn函数返回非0值)来中断遍历,不要在fn函数中使用longjmp().
照着定义写了下程序。
今天写了个ftw()函数的程序如下:
int copytoU_device(constchar *file , const struct stat *sb ,int flag)
{
if(flag == FTW_F){
printf("%s,--filen",file);
}
else if(flag == FTW_D)
{
printf("%s--dirn",file);
}
return 0;注1
}
int main(int argc ,char*argv[])
{
int result = 0;
int flag_ftw = 0;
DIR *sp;
if((sp = opendir(PATH)) == 0) //打开copy文件夹,不存在返回0
{perror("fail to open dir");
return 0;
}
flag_ftw = ftw(PATH,copytoU_device,500);
printf("%dn",flag_ftw);
closedir(sp);
if(result == 1)
{
perror("success");
}
}
刚开始 一直无法打出一个文件夹下的所有内容,所以上网查了一些资料,才知道少了上面红色字体 注 1 的那个 return0;
注释: 如果要结束ftw()的遍历,fn()只需返回一非零值即可,此值同时也会是ftw()的返回值。否则ftw()会试着走完所有的 目录,然后返回0.
得到的结果:/root/kay/copy--dir
/root/kay/copy/b,--file
/root/kay/copy/a,--file
/root/kay/copy/kk--dir
/root/kay/copy/kk/1~,--file
/root/kay/copy/kk/1,--file
ftw()函数的遍历拷贝功能可以嵌套到子文件夹下面的子文件,比如我最近写的一个程序的功能是把一个文件夹下的文件和子文件夹(里面也有文件)拷贝到另外一个文件夹下,并删除原文件和原文件夹。通过ftw()函数可以轻松的把文件找出来,但是,要copy子文件夹下的文件时,就会提示段错误 ,为什么呢 ?因为,有子文件夹“阻碍”,解决的办法很简单 ------à只要在目的文件夹中建立个与原子文件相同的文件夹就可以了,它就成自动按照你程序的要求,把子文件夹中的内容拷贝过去。
如下程序:
if(flag == FTW_F)
{
printf("%s--filen",file);
fd = fopen(file,"r");
fw = fopen(newpath,"w");
while((ch= fgetc(fd)) != EOF ) //读取文件内容
{
fputc(ch,fw);//复制到新文件中
}
fclose(fw);
fclose(fd);
printf("error = %dn",unlink(file)); //删除旧文件
}
if(flag == FTW_D)
{
printf("%s--dirn",file);
mkdir(newpath,0777);//在新路径下创建新文件夹名
if(!flag_rein)
{
countfile++;
}
rmdir(file);//删除原文件夹由于文件夹下有文件所以第一次无法删除
}
printf("%d -- countfilen",countfile);
free(newpath);
newpath = NULL;
return 0;
}
随后遇到的问题是,由于文件夹下有文件(文件夹)所以第一次无法删除,因此要删除文件夹,只好再次进入ftw()函数,进行遍历并删除,要进入几次呢?就是看你的原文件夹中嵌套了文件夹的层数了(记住你是否要删除原文件夹)。
这是个人的学习心得,和自己程序中的一部分,有不足之处,请一起探讨共同学习。