Unix/Linux编程:文件树遍历-----nftw()

2023-11-08

  • nftw()函数是对执行类似功能的老函数 ftw()的加强。由于提供了更多功能,对符号链接的处理也更易于把握
  • GNU C 语言函数库也提供了派生自 BSD 分支的 fts API(fts_open()、fts_read()、fts_children()、fts_set()和 fts_close())。这些函数执行的任务类似于 ftw()和 nftw(),但在遍历树方面为应用程序提供了更大的灵活性。
NAME
       ftw, nftw - file tree walk

SYNOPSIS
       #include <ftw.h>

       int nftw(const char *dirpath,
               int (*fn) (const char *fpath, const struct stat *sb,
                          int typeflag, struct FTW *ftwbuf),
               int nopenfd, int flags);

       #include <ftw.h>

       int ftw(const char *dirpath,
               int (*fn) (const char *fpath, const struct stat *sb,
                          int typeflag),
               int nopenfd);


nftw()函数遍历由 dirpath 指定的目录树,并为目录树中的每个文件调用一次由程序员定义的 fn 函数。

  • 默认情况下,nftw()会针对给定的树执行未排序的前序遍历,即对各目录的处理要先于各目录下的文件和子目录
  • 当nftw()遍历目录树时,最多会为树的每一层打开一个文件描述符。
  • 参数nopenfd指定了nftw()可以使用文件描述符数量的最大值
    • 如果目录树深度超过这一最大值,那么nftw()会在做好记录的前提下,关闭并重新打开描述符,从而避免同时持有的描述符数目突破上限nopenfd(从而导致运行越来越慢)
    • 在较老的 UNIX 实现中,有的系统要求每个进程可打开的文件描述符数量不得超过 20 个,这更突显出这一参数的必要性。现代 UNIX 实现允许进程打开大量的文件描述符,因此,在指定该数目时出手可以大方一些(比如,10 或者更多)。
  • nftw()的 flags 参数由 0 个或多个下列常量相或(|)组成,这些常量可对函数的操作做出修正
    • FTW_CHDIR
      • 在处理目录内容之前先调用 chdir()进入每个目录。
      • 如果打算让 func 在 pathname 参数所指定文件的驻留目录下展开某些工作,那么就应当使用这一标志。
    • FTW_DEPTH
      • 对目录树执行后序遍历。这意味着,nftw()会在对目录本身执行 func 之前先对目录中的所
        有文件(及子目录)执行 func 调用。
      • (这一标志名称容易引起误会—nftw()遍历目录树遵循的是深度优先原则,而非广度优先。而这一标志的作用其实就是将先序遍历改为后序遍历。
    • FTW_MOUNT
      • 不会越界进入另一文件系统。
      • 因此,如果树中某一子目录是挂载点,那么不会对其进行遍历。
    • FTW_PHYS
      • 默认情况下,nftw()对符号链接进行解引用操作。而使用该标志则告知 nftw()函数不要这么做。相反,函数会将符号链接传递给 func 函数,并将 typeflag 值置为 FTW_SL。

nftw()为每个文件调用 func 时传递 4 个参数。

  • 第一个参数 pathname 是文件的路径名。这个路径名可以是绝对路径,也可以是相对路径。
    • 如果指定 dirpath 时使用的是绝对路径,那么pathname 就可能是绝对路径。
    • 反之,如果指定 dirpath 时使用的是相对路径名,则 pathname中的路径可能是相对于进程调用 ntfw()时的当前工作目录而言。
  • 第二个参数 statbuf 是一枚指针,指向 stat 结构,内含该文件的相关信息。
  • 第三个参数 typeflag 提供了有关该文件的深入信息,并具有如下特征值之一
    • FTW_D :这是一个目录。
    • FTW_DNR :这是一个不能读取的目录(所以 nftw()不能遍历其后代)。
    • FTW_DP :正在对一个目录进行后序遍历,当前项是一个目录,其所包含的文件和子目录已经处理完毕。
    • FTW_F :该文件的类型是除目录和符号链接以外的任何类型。
    • FTW_NS :对该文件调用 stat()失败,可能是因为权限限制。Statbuf 中的值未定义。
    • FTW_SL :这是一个符号链接。仅当使用
    • FTW_PHYS :标志调用 nftw()函数时才返回该值。
    • FTW_SLN :这是一个悬空的符号链接。仅当未在flags参数中指定FTW_PHYS标志时才会出现该值
  • Func 的第四个参数 ftwbuf 是一枚指针,所指向结构定义如下:
    • 该结构的 base 字段是指 func 函数中 pathname 参数内文件名部分(最后一个“/”字符之后的部分)的整型偏移量
    • level 字段是指该条目相对于遍历起点(其 level 为 0)的深度
struct FTW{
	int base;
	int level;
};

每次调用 func 都必须返回一个整型值,由 nftw()加以解释。

  • 如果返回 0,nftw()会继续对树进行遍历,如果所有对 func 的调用均返回 0,那么 nftw()本身也将返回 0 给调用者。
  • 若返回非 0 值,则通知 nftw()立即停止对树的遍历,这时nftw()也会返回相同的非 0 值

由于 nftw()使用的数据结构是动态分配的,故而应用程序提前终止目录树遍历的唯一方法就是让 func 调用返回一个非 0 值

#if defined(__sun)
#define _XOPEN_SOURCE 500       /* Solaris 8 needs it this way */
#else
#if ! defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600
#define _XOPEN_SOURCE 600       /* Get nftw() and S_IFSOCK declarations */
#endif
#endif
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

static void
usageError(const char *progName, const char *msg)
{
    if (msg != NULL)
        fprintf(stderr, "%s\n", msg);
    fprintf(stderr, "Usage: %s [-d] [-m] [-p] [directory-path]\n", progName);
    fprintf(stderr, "\t-d Use FTW_DEPTH flag\n");
    fprintf(stderr, "\t-m Use FTW_MOUNT flag\n");
    fprintf(stderr, "\t-p Use FTW_PHYS flag\n");
    exit(EXIT_FAILURE);
}
static int                      /* Function called by nftw() */
dirTree(const char *pathname, const struct stat *sbuf, int type,
        struct FTW *ftwb)
{
    if (type == FTW_NS) {                  /* Could not stat() file */
        printf("?");
    } else {
        switch (sbuf->st_mode & S_IFMT) {  /* Print file type */
            case S_IFREG:  printf("-"); break;
            case S_IFDIR:  printf("d"); break;
            case S_IFCHR:  printf("c"); break;
            case S_IFBLK:  printf("b"); break;
         //   case S_IFLNK:  printf("l"); break;
            case S_IFIFO:  printf("p"); break;
           // case S_IFSOCK: printf("s"); break;
            default:       printf("?"); break; /* Should never happen (on Linux) */
        }
    }

    printf(" %s  ", (type == FTW_D)  ? "D  " : (type == FTW_DNR) ? "DNR" :
                                               (type == FTW_DP) ? "DP " : (type == FTW_F)   ? "F  " :
                                                                          (type == FTW_SL) ? "SL " : (type == FTW_SLN) ? "SLN" :
                                                                                                     (type == FTW_NS) ? "NS " : "  ");

    if (type != FTW_NS)
        printf("%7ld ", (long) sbuf->st_ino);
    else
        printf("        ");

    printf(" %*s", 4 * ftwb->level, "");        /* Indent suitably */
    printf("%s\n",  &pathname[ftwb->base]);     /* Print basename */
    return 0;                                   /* Tell nftw() to continue */
}
int
main(int argc, char *argv[])
{
    int flags, opt;

    flags = 0;
    while ((opt = getopt(argc, argv, "dmp")) != -1) {
        switch (opt) {
            case 'd': flags |= FTW_DEPTH;   break;
            case 'm': flags |= FTW_MOUNT;   break;
            case 'p': flags |= FTW_PHYS;    break;
            default:  usageError(argv[0], NULL);
        }
    }

    if (argc > optind + 1)
        usageError(argv[0], NULL);

    if (nftw((argc > optind) ? argv[optind] : ".", dirTree, 10, flags) == -1) {
        perror("nftw");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unix/Linux编程:文件树遍历-----nftw() 的相关文章

  • vsftpd的安装和使用

    目录 1 vsftpd的简介 2 2 特点 2 3 安装 2 4 创建虚拟用户 2 5 vsftpd服务器的配置 4 6 vsftpd配置文件说明 7 7 防火墙的配置 8 8 vsftpd的验证 9 9 vsftpd的常用命令 10 10
  • sql 递归查询_SQL如何求解递归问题?

    点击上方SQL数据库开发 关注获取SQL视频教程 SQL专栏SQL数据库基础知识汇总SQL数据库高级知识汇总 递归 递归是指程序调用自身的一种编程技巧 在SQL中也有递归查询 下面我们通过一个省市区的示例来讲解递归查询的用法 问题 有如下一
  • 【C语言刷题2】

    1 杨辉三角 思路 首先观察一下示例 会发现需要一个二维数组来帮助解题 根据题目描述 会发现每一行的元素个数等于行数 并且每行首尾元素都是1 中间的元素都是左上角和上方元素和 这样我们就可以建立一个选择语句if else 如果是每行第一个或
  • UE4 C++ Timeline

    UE4 C Timeline 我命名有点不规范注意点看 结束事件绑定 每次更改绑定 调用时间轴开始方法方法 1 先建C 类 用碰撞触发时间轴 代码 h Fill out your copyright notice in the Descri
  • Compareable接口的compareTo方法详解

    Compareable接口可以实现类中成员属性的排序方法 通过重写Compareable接口中的CompareTo方法实现自定义规则的排序 针对Compareable接口的排序方式 将通过对学生类和测试类进行一个代码演示 一般情况下 一般情
  • Java用集合实现斗地主洗牌发牌

    案列分析 准备4种花色牌与13种数值牌循环嵌套为52张牌 加两种特殊牌大王小王牌共54种 再进行洗牌发牌 文章目录 一 思路分析 二 准备牌 1 准备一个集合存放所有牌 2 准备两个数组分别存取扑克牌的4种花色和13种数值 3 进行嵌套组合
  • 调度器简介,以及Linux的调度策略

    进程是操作系统虚拟出来的概念 用来组织计算机中的任务 但随着进程被赋予越来越多的任务 进程好像有了真实的生命 它从诞生就随着CPU时间执行 直到最终消失 不过 进程的生命都得到了操作系统内核的关照 就好像疲于照顾几个孩子的母亲内核必须做出决
  • Linux找回密码

    Linux找回密码 1 开启的时候要尽快点击键盘上下键 选中上面一个 然后输入 e 2 然后点击键盘上下键 找到linux16开头这一行 在行的最后输入 init bin sh 3 接着 输入完成后 直接按快捷键 Ctrl x 进入单用户模
  • CSDN的chatGPT为什么会有很多问题无法回答?

    ChatGPT是一个被OpenAI训练的大型语言模型 它使用机器学习算法 可以根据上下文和用户的输入来回答问题 然而 由于我们的认知有限 有时ChatGPT无法正确理解用户的问题或句子 从而导致它无法给出准确的回答
  • 登录文档服务器,开启登录服务器

    开启登录服务器 内容精选 换一换 如果您已在购买存储库时绑定服务器 文件系统或磁盘 可以跳过此章节 云服务器备份存储库 SFS Turbo备份存储库和云硬盘备份存储库创建后 通过向存储库绑定服务器 文件系统或磁盘来进行备份 复制操作 当混合
  • C++学习之new 与 delete表达式

    new和delete表达式动态创建和释放单个对象 a 基本知识介绍 定义变量时 必须指定其数据类型和名字 而动态创建对象时只需指定其数据类型而不必为该对象命名 取而代之的是 new表达式返回新创建对象的指针 我们通过指针来访问此对象 int
  • 解决ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘问题

    解决ImportError Could not find the DLL s msvcp140 1 dll 问题 刚安装好tensorflow安装包去试试import tensorflow as ft时 出现错误 错误原因 ImportEr
  • 【项目实战】---需求分析+表关系分析

    SSH 小编初次接触的时候傻傻的以为这个跟SHE有什么关系呢 又是哪路明星歌手 后来才知道小编又土鳖了 原来SSH是这个样子滴 百度百科对她这样阐述 SSH即 Spring Struts Hibernate Struts对Model Vie
  • Python员工离职数据分析

    Python员工离职数据分析 import pandas as pd import seaborn as sns import matplotlib pyplot as plt import warnings warnings filter
  • 2022年国际土木与海洋工程联合会议(JCCME 2022)

    海南大学主办 2022年国际土木与海洋工程联合会议 JCCME 2022 重要信息 会议网址 www jccme org 会议时间 2022年12月23 25日 召开地点 海口 截稿时间 2022年11月20日 录用通知 投稿后2周 收录检
  • git官网进去很慢我们可以去镜像下载

    git下载
  • 五脏六腑在脸上的反射区图片_人体五大反射区的有图详解。

    原标题 人体五大反射区的有图详解 反射区是遍布全身的神经聚集点 与身体各器官相对应 比如手 足 耳等反射区 它们与身体的五脏六腑 头部的大小脑 淋巴腺 内分泌腺 肌肉 关节紧密相连 其中 每个器官 部位的神经末梢 在手 足 耳等部位都有一个

随机推荐

  • antV G2 常用指标参数 01

    antV G2 会比较多的API 查看起来也比较费时间 所以把一些常有的方法 参数 指标列举 方便运用 01 柱状图两边留空间 time 是横坐标的 指标 chart scale time range 0 05 0 95 02 自定义纵坐标
  • Linux查找特定进程信息

    命令 查找ssh进程 root linuxcentos ps ef grep ssh 执行结果 root 1303 1 0 Apr17 00 00 00 usr sbin sshd root 3260 3087 0 Apr17 00 00
  • matlab中std函数的用法,matlab std函数 用法及实例

    MATLAB常常用到std函数来进行标准差计算 下面我就通过实例介绍一下 matlab std函数怎么用 1 std函数是用来计算标准偏差的一个函数 由于其有不同的参数 我们就用下面的例子进行介绍 A 1 2 3 1 1 1 标准差的两种计
  • Java中HashMap原理与分析

    HashMap的底层数据结构 HashMap是以Key Value的方式进行数据结构存储的一种数据结构 JDK1 7采用的是数组 链表 使用Entry类存储key和value JDK1 8采用的是数组 链表 红黑树 使用Node类存储key
  • 智星云AI主机docker使用指南

    智星云AI云主机默认提供docker安装 用户只需要在算力市场 点击 AI云主机 选择Centos或者Ubuntu系统即可租用到安装好docker的云主机 图1 算力市场 登录上云主机后 我们首先运行一个简单的docker hello wo
  • vue全局组件的引入

    1 创建组件 在自定义组件的文件夹下 layout 创建组件 并创建index js文件 2 导出组件 在index js内导出组件 可以同时注册多个组件 代码如下 import QRcode from components layout
  • 一些web工具的原理

    1 子域名收集工具 通过枚举可能的子域名并尝试进行DNS解析来确定是否存在有效的子域名 2 设备发现工具 通过发送 ICMP 或 ARP数据包给目标 观察目标返回的信息来判断设备是否活跃 或是通过直接向端口发送 TCP UDP 等网络请求
  • flutter图片点击跳转_Flutter “跳转页面”(一)

    跳转页面 为啥加双引号 其实所谓的跳转页面可能和以前认识的不太一样 因为在Flutter里 所有能看到的东西一般都是widget 但是 没有说那个app是由一个页面构成的 所以 这个概念确实还是有的 这个功能的实现需要用到两个东西Route
  • Vue报错Custom elements in iteration require 'v-bind:key' directives."错误解决

    错误代码
  • 造一台机器人需要哪些技能?

    转自 帐号已迁移 大家好 我是小王 是一名刚刚加入机器人队的大学生 有人说搞机器人特别简单 只要画画图 拧拧螺丝 敲敲代码就可以了 He tui 要这么容易 每年能有上百支机器人队伍 花十几万挤破了头都抢不到30万奖金吗 不过 团队有了我这
  • Osmosis 0.46详细使用说明

    原文地址 http wiki openstreetmap org wiki Osmosis Detailed Usage 0 46 全局选项 Short Option Long Option Description v verbose 需要
  • 图神经网络基础(part 1)

    文章目录 一 图的基本概念 二 简易图谱论 2 1 拉普拉斯矩阵 2 2 拉普拉斯二次型 2 3 拉普拉斯矩阵与图扩散 2 4 图论傅里叶变换 一 图的基本概念 对于接触过数据结构和算法的人来说 图并不是一个陌生的概念 一个图 Graph
  • 解释器-架构案例2021(三十一)

    软件架构设计与评估 某公司支持用户使用浏览器在线进行基于机器学习的智能应用开发活动 该平台核心应用场景是用户拖拉拽算法组件灵活定义机器学习流程 采用自助方式智能应用设计 实现与部署 并开发新算法加入平台 a 平台用户分为算法工程师 软件工程
  • markdown使用手册

    目录 记录 04 学会用SLA评估系统 功能快捷键 合理的创建标题 有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中 居左 居右 SmartyPants 创建一
  • 前端上传组件Plupload使用指南 与swfupload一样强大

    http blog csdn net z69183787 article details 46698741 Plupload 是一款由著名的web编辑器 TinyMCE 团队开发的上传组件 简单易用且功能强大 我们完全可以使用Pluploa
  • 静态资源加载不到解决办法

    这是我总结的几种解决办法 可以自行尝试实在不行都加上 第一种在springmvc配置文件当中加入资源映射
  • 选课微信小程序开发 java

    1 使用技术 java springboot mysql hibernate 微信小程序 2 功能介绍 后台管理 学生管理 课程管理 类型管理 选课管理 操作中心 管理员中心 导入导出学生 微信小程序端 学生端 查看课程 选课 查看选课课程
  • 网络爬虫是怎么运行的

    2 2 1知识概述 网络爬虫究竟是怎么运行的 单个页面是如何运行的 1 指定一个url 2 使用技术发送get请求 3 获得服务端的响应 4 将二进制的数据 转化成HTML文档 网络爬虫一般会爬取很多很多很多的页面 for 1 指定一个ur
  • 如何在TheBrain中为Plex选择自定义图像并更改默认字体?

    TheBrain 点击下载 您的终极数字记忆和无限思维导图软件 我们从一个想法跳到另一个想法 构建越来越复杂的网络 直到新想法形成 TheBrain允许你以同样的方式组织你的信息 而不限制你预先确定的文件结构 事实上 你的数字大脑是没有限制
  • Unix/Linux编程:文件树遍历-----nftw()

    nftw 函数是对执行类似功能的老函数 ftw 的加强 由于提供了更多功能 对符号链接的处理也更易于把握 GNU C 语言函数库也提供了派生自 BSD 分支的 fts API fts open fts read fts children f