zoukankan      html  css  js  c++  java
  • TLPI读书笔记第18章-目录与链接3

    1.列出目录中的所有文件

    /* Listing 18-2 */
    
    /* list_files.c*/
    #if defined(__APPLE__)
    /* Darwin requires this header before including <dirent.h> */
    #include <sys/types.h>
    #endif
    
    #include <dirent.h>
    #include "tlpi_hdr.h"
    
    static void             /* 列出目录'dirpath'的所有文件 */
    listFiles(const char *dirpath) {
        DIR *dirp;
        struct dirent *dp;
        Boolean isCurrent;          /* 判断dirpath是否是当前目录. */
    
        isCurrent = strcmp(dirpath, ".") == 0;
    /**打开指定目录,返回一个DIR指针*/
        dirp = opendir(dirpath);
        if (dirp == NULL) {
            errMsg("opendir failed on '%s'", dirpath);
            return;
        }
    
        /* 读取每个DIR条目,打印目录+文件名 */
    
        for (;;) {
            errno = 0;              /* 打印readdir过程中错误 */
            dp = readdir(dirp);
            if (dp == NULL)
                break;
         /**如果d_name是.或..,继续循环*/
            if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
                continue;
         /**如果是当前目录,则不打印dir部分*/
            if (!isCurrent)
                printf("%s/", dirpath);
            printf("%s
    ", dp->d_name);
        }
    
        if (errno != 0)
            errExit("readdir");
    
        if (closedir(dirp) == -1)
            errMsg("closedir");
    }
    
    int
    main(int argc, char *argv[]) {
        if (argc > 1 && strcmp(argv[1], "--help") == 0)
            usageErr("%s [dir-path...]
    ", argv[0]);
    
        if (argc == 1)              /* 没有传参数,则默认是当前目录. */
            listFiles(".");
        else
            for (argv++; *argv; argv++)
                listFiles(*argv);
    
        exit(EXIT_SUCCESS);
    }

    2.递归遍历目录

    /* Listing 18-3 */
    
    /* nftw_dir_tree.c
    
    */
    #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 "tlpi_hdr.h"
    
    static void
    usageError(const char *progName, const char *msg)
    {
        if (msg != NULL)
            fprintf(stderr, "%s
    ", msg);
        fprintf(stderr, "Usage: %s [-d] [-m] [-p] [directory-path]
    ", progName);
        fprintf(stderr, "	-d Use FTW_DEPTH flag
    ");
        fprintf(stderr, "	-m Use FTW_MOUNT flag
    ");
        fprintf(stderr, "	-p Use FTW_PHYS flag
    ");
        exit(EXIT_FAILURE);
    }
    
    static int                      /* 自定义函数,以备nftw()调用 */
    dirTree(const char *pathname, const struct stat *sbuf, int type,struct FTW *ftwb)
    {
        if (type == FTW_NS) {                  /* 调用stat失败 */
            printf("?");
        } else {
            switch (sbuf->st_mode & S_IFMT) {  /* 打印文件类型 */
            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, "");        /* 用缩进代表级别 */
        printf("%s
    ",  &pathname[ftwb->base]);     /* 打印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);
    }

    3.打印路径中的目录和文件名

    /* Listing 18-5 */
    
    /* t_dirbasename.c
    
    */
    #include <libgen.h>
    #include "tlpi_hdr.h"
    /**打印路径的目录部分和文件名部分
     * dirname()和 basename()均可修改pathname所指向的字符串。
     * 因此,如果希望保留原有的路径名字符串,那么就必须向 dirname()和 basename()传递该字符串的副本
     * 使用strdup()该函数调用了 malloc()来制作传递给dirname()和basename()的字符串副本,
     * 然后再使用 free()将其释放
     * */
    int
    main(int argc, char *argv[])
    {
        char *t1, *t2;
        int j;
    
        for (j = 1; j < argc; j++)  {
            t1 = strdup(argv[j]);
            if (t1 == NULL)
                errExit("strdup");
            t2 = strdup(argv[j]);
            if (t2 == NULL)
                errExit("strdup");
    
            printf("%s ==> %s + %s
    ", argv[j], dirname(t1), basename(t2));
    
            free(t1);
            free(t2);
        }
    
        exit(EXIT_SUCCESS);
    }

    4.unlink的应用

    /* Listing 18-1 */
    
    /** t_unlink.c
        一个文件被unlink,当他还有被打开的文件描述符时他实际是没有被删的,
        此时还能进行写入,close(fd)后文件才真正被删
        Usage: t_unlink file
    */
    #include <sys/stat.h>
    #include <fcntl.h>
    #include "tlpi_hdr.h"
    
    #define CMD_SIZE 200
    #define BUF_SIZE 1024
    
    int
    main(int argc, char *argv[])
    {
        int fd, j, numBlocks;
        char shellCmd[CMD_SIZE];            /* 调用的shell命令 */
        char buf[BUF_SIZE];                 /* 随机写入一定字节 */
    
        if (argc < 2 || strcmp(argv[1], "--help") == 0)
            usageErr("%s temp-file [num-1kB-blocks] 
    ", argv[0]);
    
        numBlocks = (argc > 2) ? getInt(argv[2], GN_GT_0, "num-1kB-blocks")
                               : 100000;
    
        /* 创建一个新文件 */
    
        fd = open(argv[1], O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
        if (fd == -1)
            errExit("open");
    
        if (unlink(argv[1]) == -1)          /* 删除文件 */
            errExit("unlink");
    
        for (j = 0; j < numBlocks; j++)     /* 写入文件 */
            if (write(fd, buf, BUF_SIZE) != BUF_SIZE)
                fatal("partial/failed write");
        /**将命令df写入shellCmd中,并执行shell命令*/
        snprintf(shellCmd, CMD_SIZE, "df -k `dirname %s`", argv[1]);
        system(shellCmd);                   /* 查看文件占用空间 */
    
        if (close(fd) == -1)                /* 关闭文件描述符,此时文件才被删除 */
            errExit("close");
        printf("********** Closed file descriptor
    ");
    
        system(shellCmd);                   /* 重新查看占用空间 */
        exit(EXIT_SUCCESS);
    }

    5.读取并解析一个符号链接

    /* Listing 18-4 */
    
    /* view_symlink.c
    
       读取并解析一个符号链接
    */
    #include <sys/stat.h>
    #include <limits.h>             /* For definition of PATH_MAX */
    #include "tlpi_hdr.h"
    
    #define BUF_SIZE PATH_MAX
    
    int
    main(int argc, char *argv[])
    {
        struct stat statbuf;
        char buf[BUF_SIZE];
        ssize_t numBytes;
    
        if (argc != 2 || strcmp(argv[1], "--help") == 0)
            usageErr("%s pathname
    ", argv[0]);
    
        /* 检查提供的路径名是否为一个符号链接 */
    
        if (lstat(argv[1], &statbuf) == -1)
            errExit("lstat");
    
        if (!S_ISLNK(statbuf.st_mode))
            fatal("%s is not a symbolic link", argv[1]);
    
        numBytes = readlink(argv[1], buf, BUF_SIZE - 1);
        if (numBytes == -1)
            errExit("readlink");
        buf[numBytes] = '';                       /* 添加终止空字节,并打印 */
        printf("readlink: %s --> %s
    ", argv[1], buf);
    
        if (realpath(argv[1], buf) == NULL)
            errExit("realpath");
        printf("realpath: %s --> %s
    ", argv[1], buf);
    
        exit(EXIT_SUCCESS);
    }
  • 相关阅读:
    Sql Server数据库使用触发器和sqlbulkcopy大批量数据插入更新
    树莓派安装系统
    ubuntu设置ulimit
    aws申请ec2实例后如何用root用户登录
    python-redis
    Windows Server多用户同时远程登录
    ansible-常用模块
    ansible安装-本机测试
    cmdb实现三种方式
    linux-crond_计划任务
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/14663985.html
Copyright © 2011-2022 走看看