zoukankan      html  css  js  c++  java
  • UNIXLINUX编程实践教程>第四章>实例代码注解>pwd1

    一 问题

      实现pwd功能

    二 分析

      结合stat()函数和stat结构体,可根据目录名获得目标的i-节点号
      使用chdir()函数可以改变用户的当前路径
      结合readdir()函数和direntp结构体,可以根据i-节点号获得其对应的目录名称
      1)获得当前目录A的i-节点号Ai
      2)跳转到父目录,根据i-节点号Ai就能知道目录A的名称
      3)依次倒退到根目录为止

    三 实现

    1 头文件

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <stdlib.h>
    #include <string.h>

    2 相关函数声明

    ino_t get_inode(char *);
    void printpathto(ino_t);
    void inum_to_name(ino_t,char *,int);

    3 根据目录名称获得其i-节点号

    ino_t get_inode(char *fname)
    {
        struct stat info;
        /*根据目录名获得目录的stat结构信息*/
        if(stat(fname,&info)==-1)
        {
            fprintf(stderr,"Cannot stat");
            perror(fname);
            exit(1);
        }
        /*i-节点信息存储在stat结构的st_ino中*/
        return info.st_ino;
    }

    4 目录的跳转

    使用chdir()函数即可

    5 根据i-节点号获得目录名称

    void inum_to_name(ino_t inode_to_find,char * namebuf,int buflen)
    {
        DIR *dir_ptr;
        struct dirent *direntp;
        dir_ptr  = opendir(".");
        if(dir_ptr == NULL)
        {
            perror(".");
            exit(1);
        }
        /*用readdir函数打开目录并获得dirent结构体*/
        while((direntp = readdir(dir_ptr))!=NULL)
        {
            /*目录内的文件节点号存储在dirent结构体的d_ino中*/
            if(direntp->d_ino == inode_to_find)
            {
                /*比较两个i-节点号,一致的话就通过dirent结构体获得目录名称*/
                strncpy(namebuf,direntp->d_name,buflen);
                namebuf[buflen-1] = '\0';
                closedir(dir_ptr);
                return;
            }
        }
        fprintf(stderr,"error looking for inum \n");
        exit(1);
    }

    6 根据目录名,获得其路径

    在任何目录下,“.”表示当前目录,“..”表示父目录

    void printpathto(ino_t this_inode)
    {
        ino_t my_inode;
        char its_name[BUFSIZ];
        /*首先判断父目录与当前目录的i-节点号是否一致(根目录的父目录与当前目录的i-节点号一致)*/
        if (get_inode("..") != this_inode)
        {
            /*跳到父目录*/
            chdir("..");
            /*根据i-节点号查询当前目录的目录名*/
            inum_to_name(this_inode,its_name,BUFSIZ);
            /*获得父目录的i-节点号*/
            my_inode = get_inode(".");
            /*循环调用*/
            printpathto(my_inode);
            /*当前目录的父目录为根目录时,结束循环调用并打印路径*/
            printf("/%s",its_name);
        }
    }

    7 主函数

    int main()
    {
        /*根据当前目录的i-节点号,获得当前路径*/
        printpathto(get_inode("."));
        putchar('\n');
        return 0;
    }

    四 相关函数与结构体

    1 stat()函数
    通过文件名获取文件信息,并保存在stat结构体中
    头文件:#include <sys/stat.h>  #include <unistd.h>
    函数原型 int stat(const char *file_name, struct stat *buf)
    参数    file_name 指向文件名的指针
          buf 指向stat结构体的指针
    返回值   0 执行成功
          -1 执行失败,错误代码存于ermo中

    2 stat结构体
    头文件:#include<sys/stat.h>
    struct stat
    {
      mode_t st_mode; //文件对应的模式,文件,目录等
      ino_t st_ino; //i-node节点号
      dev_t st_dev; //设备号码
      dev_t st_rdev; //特殊设备号码
      nlink_t st_nlink; //文件的连接数
      uid_t st_uid; //文件所有者
      gid_t st_gid; //文件所有者对应的组
      off_t st_size; //普通文件,对应的文件字节数
      time_t st_atime; //文件最后被访问的时间
      time_t st_mtime; //文件内容最后被修改的时间
      time_t st_ctime; //文件状态(属性)改变时间
      blksize_t st_blksize; //文件内容对应的块大小
      blkcnt_t st_blocks; //文件内容对应的块数量

    }

    3 DIR结构体
    typedef struct _dirstream DIR;
    struct _dirstream
    {
      void *_fd; /* `struct hurd_fd' pointer for descriptor. */
      char *_data; /* Directory block. */
      int _entry_data; /* Entry number `__data' corresponds to. */
      char *_ptr; /* Current pointer into the block. */
      int _entry_ptr; /* Entry number `__ptr' corresponds to. */
      size_t _allocation; /* Space allocated for the block. */
      size_t _size; /* Total valid data in the block. */
      _libc_lock_define (, _lock) /* Mutex lock for this structure. */
    }

    4 opendir()函数
    打开一个目录,失败时返回一个空指针
    头文件:#inculde<dirent.h>
    函数原型 DIR* opendir (const char * path );
    参数    path 目录的路径
    返回值   DIR* 一个用来保存目录信息结构体指针
          NULL 打开失败

    5 dirent结构体
    struct dirent
    {
      long d_ino; /* inode number 索引节点号 */
      off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
      unsigned short d_reclen; /* length of this d_name 文件名长 */
      unsigned char d_type; /* the type of d_name 文件类型 */
      char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
    }

    6 readdir()函数
    读取目录,然后返回dirent结构体指针
    头文件:#include<dirent.h>
    函数原型 struct dirent* readdir(DIR* dir_handle);
    参数 dir_handle 保存目录信息的DIR结构体指针
    返回值 dirent 结构体指针
    NULL 文件读取完毕

    7 closedir()函数
    关闭参数dir所指的目录流,关闭成功返回0,失败返回-1
    头文件:  #include<dirent.h>
    函数原型  int closedir(DIR *dir);
    参数    dir 指向要关闭的目录流
    返回值    0 成功
                -1 失败,错误原因存于errno中

    8 strncpy()函数
    将字符串src中最多n个字符复制到字符数组dest中,返回指向dest的指针
    头文件:  #include <string.h>
    函数原型  char * strncpy(char *dest, char *src, size_t n);
    参数    dest 指向目的的指针
          src 指向源的指针
    返回值   char * 指向dest的指针

    9 chdir()函数
    用于改变当前工作目录
    头文件:  #include <unistd.h>

    函数原型  int chdir ( const char *path );
    参数    path 指定的目录
    返回值   0 成功
          -1 失败

     

  • 相关阅读:
    .NET Core 玩一玩 Ocelot API网关
    VUE.js 中取得后台原生HTML字符串 原样显示问题
    简单了解 iTextSharp实现HTML to PDF
    ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下
    C# AutoMapper 了解一下
    玩一玩基于Token的 自定义身份认证+权限管理
    ASP.NET MVC5 实现基于Quartz.NET任务调度
    ASP.NET MVC5 使用NPOI导出ExceL 返回浏览器下载
    [python][openpyxl]读取excel中公式的结果值
    Python实例001:实现识别图片中的文字
  • 原文地址:https://www.cnblogs.com/cation/p/2931685.html
Copyright © 2011-2022 走看看