在 Linux 上使用目录进行 C 编程

举报
Tiamo_T 发表于 2022/06/22 17:48:03 2022/06/22
【摘要】 在本文中,我们将通过示例介绍目录编程的以下基础知识。

当有人说在 Linux 中一切都是文件时,它确实是正确的。我们可以对文件执行的大多数操作都可以在其他实体上完成,例如套接字、管道、目录等。
在某些情况下,软件实用程序可能必须穿越 Linux 系统中的目录才能找到或匹配某些内容。这是该实用程序的程序员必须处理目录编程的用例。因此,在本文中,我们将通过示例介绍目录编程的以下基础知识。

  1.  创建目录。
  2.  阅读目录。
  3.  删除目录。
  4.  关闭目录。
  5.  获取当前工作目录。

我们将介绍用于上述每个步骤的函数,最后我们将看到一个总结所有目录操作的示例。

1. 创建目录

Linux 系统提供以下系统调用来创建目录:

#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t 模式);

'pathname' 参数用于目录的名称

2.阅读目录

一系列函数用于读取目录的内容。

1.首先需要打开一个目录流。这是通过以下系统调用完成的:

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);

从手册页:

opendir() 函数打开一个目录名对应的目录流,并返回一个指向目录流的指针。流位于目录中的第一个条目。

2. 接下来,为了读取目录中的条目,上面打开的流被以下系统调用使用:

#include
struct dirent *readdir(DIR *dirp);

从手册页:

readdir() 函数返回一个指向 dirent 结构的指针,该结构表示 dirp 指向的目录流中的下一个目录条目。它在到达目录流的末尾或发生错误时返回 NULL。

在 Linux 上,dirent 结构定义如下:

struct dirent
{
    ino_t          d_ino;       /* inode number */
    off_t          d_off;       /* offset to the next dirent */
    unsigned short d_reclen;    /* length of this record */
    unsigned char  d_type;      /* type of file; not supported
                                   by all file system types */
    char           d_name[256]; /* filename */
};

3. 删除目录

Linux 系统提供以下系统调用来删除目录:

#include <unistd.h>
int rmdir(const char *pathname);

从手册页:

如果 'pathname' 为空,则 rmdir() 删除由 'pathname' 表示的目录。如果目录不为空,则此函数不会成功。

4. 关闭目录

Linux 系统提供以下系统调用来关闭目录:

#include <sys/types.h>
#include <dient.h>
int closedir(DIR *dirp);

从手册页:

closedir() 函数关闭与 dirp 关联的目录流。成功调用 closedir() 也会关闭与 dirp 关联的底层文件描述符。在此调用之后,目录流描述符 dirp 不可用。

5. 获取当前工作目录

Linux 系统提供以下系统调用来获取 CWD:

#include <unistd.h>
char *getcwd(char *buf, size_t size);

从手册页:

getcwd()函数将当前工作目录的绝对路径名复制到buf指向的数组中,该数组的长度为大小。该函数返回一个以null结尾的字符串,其中包含一个绝对路径名,即当前工作目录调用过程。路径名作为函数结果返回,并通过参数 buf(如果存在)返回。如果当前工作目录的绝对路径名长度(包括终止空字节)超过size字节,则返回NULL,并将errno设置为ERANGE;应用程序应检查此错误,并在必要时分配更大的缓冲区。

6. 一个例子

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

int main (int argc, char *argv[])
{
    if(2 != argc)
    {
        printf("\n Please pass in the directory name \n");
        return 1;
    }

    DIR *dp = NULL;
    struct dirent *dptr = NULL;
    // Buffer for storing the directory path
    char buff[128];
    memset(buff,0,sizeof(buff));

    //copy the path set by the user
    strcpy(buff,argv[1]);

    // Open the directory stream
    if(NULL == (dp = opendir(argv[1])) )
    {
        printf("\n Cannot open Input directory [%s]\n",argv[1]);
        exit(1);
    }
    else
    {
        // Check if user supplied '/' at the end of directory name.
        // Based on it create a buffer containing path to new directory name 'newDir'
        if(buff[strlen(buff)-1]=='/')
        {
            strncpy(buff+strlen(buff),"newDir/",7);
        }
        else
        {
            strncpy(buff+strlen(buff),"/newDir/",8);
        }

        printf("\n Creating a new directory [%s]\n",buff);
        // create a new directory
        mkdir(buff,S_IRWXU|S_IRWXG|S_IRWXO);
        printf("\n The contents of directory [%s] are as follows \n",argv[1]);
        // Read the directory contents
        while(NULL != (dptr = readdir(dp)) )
        {
            printf(" [%s] ",dptr->d_name);
        }
        // Close the directory stream
        closedir(dp);
        // Remove the new directory created by us
        rmdir(buff);
        printf("\n");
    }

    return 0;
}

上面的例子现在应该是不言自明的了。

上面例子的输出是:

# ./direntry /home/himanshu/practice/linux

 Creating a new directory [/home/himanshu/practice/linux/newDir/]

 The contents of directory [/home/himanshu/practice/linux] are as follows
 [redhat]  [newDir]  [linuxKernel]  [..]  [ubuntu]  [.]
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。