13.2.4 目录操作

来源:互联网 发布:网络直播 用英文怎么说 编辑:程序博客网 时间:2024/06/05 16:48

13.2.4  目录操作

新建目录操作可使用函数mkdir()实现,该函数的一般形式是:

 

mkdir(路径, umask)

 

当目录被成功创建函数的返回值为0,否则为–1

获得当前子目录的操作可使用函数getcwd(),该函数的一般形式是:

 

getcwd(char *buf, size_t size);

 

其中,*buf是存放当前目录的缓冲区,size是缓冲区的大小。如果函数返回当前目录的字符串长度超过size规定的大小,它将返回NULL

执行程序的工作目录就是当前子目录,如果要改变执行程序的工作目录,可以使用函数chdir()。这个函数的作用如同shell里的cd命令一样,它的一般形式是:

 

chdir(路径);

 

另一个常用目录操作是扫描子目录,与此相关的函数被封装在头文件dirent.h里。它们使用一个名为DIR的结构作为子目录处理的基础,这个结构的指针所指向的内存空间被称之为子目录流。与子目录流操作相关的函数如表13.7所示。

13.7  子目录流操作相关函数

   

   

DIR *opendir(const char *name);

打开路径并建立子目录流,返回子目录流指针

struct dirent *readdir(DIR *dirp);

函数返回一个指针,指针指向的结构里保存着子目录流dirp中下一个目录数据项的有关资料。后续的readdir调用将返回后续的目录数据。如果错误或到达子目录尾,将返回NULL

long int telldir(DIR *dirp);

函数返回值里记录着子目录流里的当前位置

void seekdir(DIR *dirp, long int loc);

dirp指定的子目录流中的目录数据项的指针进行设置。loc的值用来设置指针位置,它应该通过前一个telldir调用获得

int closedir(DIR *dirp);

关闭子目录流,返回关闭操作结果

 

下例将设计一个可遍历子目录中所有文件的函数,用于演示目录操作及目录流操作相关函数的使用方法。代码如下:

 

#include <fcntl.h>                      // 提供open()函数

#include <unistd.h>

#include <stdio.h>

#include <dirent.h>                     // 提供目录流操作函数

#include <string.h>

#include <sys/stat.h>                   // 提供属性操作函数

#include <sys/types.h>                  // 提供mode_t类型

#include <stdlib.h>

void scan_dir(char *dir, int depth) // 定义目录扫描函数

{

   DIR *dp;                              // 定义子目录流指针

   struct dirent *entry;             // 定义dirent结构指针保存后续目录

   struct stat statbuf;                 // 定义statbuf结构保存文件属性

   if((dp = opendir(dir)) == NULL) { // 打开目录,获得子目录流指针,判断操作

                                        // 是否成功

      puts("无法打开该目录");

      return;

   }

   chdir(dir);                          // 切换到当前目录中去

   while((entry = readdir(dp)) != NULL) {       // 获取下一级目录信息,如果未结

                                                // 束则循环

      lstat(entry->d_name, &statbuf);    // 获取下一级成员属性

      if(S_IFDIR & statbuf.st_mode) {    // 判断下一级成员是否是目录

         if(strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0)

continue;                     // 如果获得的成员是符号“.”和“..”,

                              // 跳过本次循环

         printf("%*s%s//n",depth,"",entry->d_name);  // 输出目录名称

         scan_dir(entry->d_name,depth+4);// 递归调用自身,扫描下一级目录的内容

      }

      else

         printf("%*s%s/n", depth, "", entry->d_name); // 输出属性不是目录

                                                        // 的成员

   }

   chdir("..");                                 // 回到上一级目录

   closedir(dp);                            // 关闭子目录流

}

 

该函数的作用是遍历目录,将其所有的子目录和文件输出到终端上。遍历子目录实现的方法是递归调用,首先判断子目录流指针所指向的文件是否为目录文件。如果是,该函数将调用自身去遍历子目录;如果不是,则输出文件名称,继续遍历当前目录,直到子目录流指向NULL。函数的depth参数作用是在子目录前增加空格的数量,每一轮递归都将增加4个空格,这样能更容易的显示出目录的层次。下面设计一个小程序进行遍历目录。

 

int main()

{

   puts("扫描/boot目录:");

   scan_dir("/boot",0);                         // 调用目录扫描函数

   puts("扫描结束");                              // 扫描结束时输出提示信息

   return 0;

}

 

程序中通过调用scan_dir()函数遍历“/boot”目录,程序的输出结果如下(有删节):

 

扫描/boot目录:

System.map-2.6.27.15-170.2.24.fc10.i686

config-2.6.27.12-170.2.5.fc10.i686

grub/

    ufs2_stage1_5

    stage1

System.map-2.6.27.12-170.2.5.fc10.i686

config-2.6.27.9-159.fc10.i686

efi/

    EFI/

        redhat/

            grub.efi

initrd-2.6.27.15-170.2.24.fc10.i686.img

vmlinuz-2.6.27.15-170.2.24.fc10.i686

扫描结束