linux ftw()函数使用方法 实例

表头文件:#include <ftw.h>
定义函数:int ftw(const char *dir, int (*fn) (const *file, const struct stat *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)(const char *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(const char *file , const struct stat *sb ,int flag)
{
    if(flag == FTW_F)
    {
        printf("%s,--file\n",file);
    }
    else if(flag == FTW_D)
    {
        printf("%s--dir\n",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("%d\n",flag_ftw);
    closedir(sp);
    if(result == 1)
    {
        perror("success");
    }
}
刚开始 一直无法打出一个文件夹下的所有内容,所以上网查了一些资料,才知道少了上面红色字体  注 1 的那个 return 0;
注释: 如果要结束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--file\n",file);
        fd = fopen(file,"r");
        fw = fopen(newpath,"w");
        while((ch = fgetc(fd)) != EOF ) //读取文件内容          
        {
            fputc(ch,fw);               //复制到新文件中
        }
        fclose(fw);
        fclose(fd);
        printf("error = %d\n",unlink(file)); //删除旧文件
     
    }
    if(flag == FTW_D)
    {
        printf("%s--dir\n",file);
        mkdir(newpath,0777);       //在新路径下创建新文件夹名
        if(!flag_rein)
        {
            countfile++;
        }
        rmdir(file);         //删除原文件夹   由于文件夹下有文件所以第一次无法删除
       
    }
     printf("%d -- countfile\n",countfile);
     free(newpath);
     newpath = NULL;
     return 0;
}
 
随后遇到的问题是,由于文件夹下有文件(文件夹)所以第一次无法删除,因此要删除文件夹,只好再次进入ftw()函数,进行遍历并删除,要进入几次呢?就是看你的原文件夹中嵌套了文件夹的层数了(记住你是否要删除原文件夹)。
   这是个人的学习心得,和自己程序中的一部分,有不足之处,请一起探讨共同学习。
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值