P8 Linux 目录操作

目录

前言

 01 mkdir 系统调用

mkdir的代码示例

 02 rmdir删除目录 

03  打开、读取以及关闭目录

3.1 opendir()函数原型:

04 读取目录 readdir()

05 struct dirent 结构体:

06 rewinddir ()函数重置目录流

07 关闭目录 closedir ()函数

测试:打印目录下的文件名与iNode

08 getcwd() 函数当前工作目录

09 改变当前工作目录chdir()和 fchdir()

 10 remove 函数删除文件


前言

                                  

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介  :  在上两章中我们Linux的文件系统底下的目录结构

                        这一章我们学习目录文件

目录块当中有多个目录项(或叫目录条目)

每一个目录项(或目录条目)都会对应到该目录下的某一 个文件

目录项当中记录了该文件的文件名以及它的 inode 节点编号, 

所以通过目录的目录块便可以遍历找 到该目录下的所有文件以及所对应的 inode 节点。

 01 mkdir 系统调用

mkdir()函数原型

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

函数参数和返回值含义如下:

  1. pathname:需要创建的目录路径。
  2. mode:新建目录的权限设置,设置方式与 open 函数的 mode 参数一样,最终权限为(mode & ~umask)。与清0,或置1
  3. 返回值:成功返回 0;失败将返回-1,并会设置 errno。

pathname 参数指定的新建目录的路径,该路径名可以是相对路径,也可以是绝对路径,

若指定的路径 名已经存在,则调用 mkdir()将会失败。 mode 参数指定了新目录的权限,

目录拥有与普通文件相同的权限位,但是其表示的含义与普通文件却 有不同 

mkdir的代码示例

#include "stdio.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>int main()
{int ret = mkdir("./next",0777);if(-1 == ret){perror("mkdir error :");exit(-1);}return 0;
}

当执行完./a.out时在当前目录下生成一个next目录文件

 02 rmdir删除目录 

rmdir 函数函数原型:首先,使用该函数需要包含头文件。

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

函数参数和返回值含义如下: 

pathname:需要删除的目录对应的路径名,并且该目录必须是一个空目录,也就是该目录下只有.和..这 两个目录项;pathname 指定的路径名不能是软链接文件,即使该链接文件指向了一个空目录。
返回值:成功返回 0;失败将返回-1,并会设置 errno。

2.2rmdir 函数测试

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define   MY_FILE "./next"void main()
{int ret = rmdir(MY_FILE);if(-1 == ret){perror("");exit(-1);}
}

代码执行完后,刚才创建的next文件被删除

03  打开、读取以及关闭目录


打开、读取、关闭一个普通文件可以使用 open()、read()、close(),

而对于目录来说,可以使用 opendir()、readdir()和 closedir()来打开、读取以及关闭目录。

3.1 opendir()函数原型:


opendir()函数用于打开一个目录,并返回指向该目录的句柄,供后续操作使用。Opendir 是一个 C 库函数。

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

函数参数和返回值含义如下:

  1. name:指定需要打开的目录路径名,可以是绝对路径,也可以是相对路径。
  2. 返回值:成功将返回指向该目录的句柄,一个 DIR 指针(其实质是一个结构体指针),其作用类似于open函数返回的文件描述符fd,后续对该目录的操作需要使用该DIR指针变量;若调用失败,则返回NULL。


04 读取目录 readdir()

readdir()用于读取目录,获取目录下所有文件的名称以及对应 inode 号。

readdir()是 一个 C 库函数(事实上 Linux 系统还提供了一个 readdir 系统调用)

其函数原型如下所示:

#include <dirent.h> struct dirent *readdir(DIR *dirp); 

函数参数和返回值含义如下:

  1. dirp:目录句柄 DIR 指针。
  2. 返回值:返回一个指向 struct dirent 结构体的指针,该结构体表示 dirp 指向的目录流中的下一个目录条目。在到达目录流的末尾或发生错误时,它返回 NULL。

Tips:“流”是从自然界中抽象出来的一种概念,有点类似于自然界当中的水流,

在文件操作中,文件 内容数据类似池塘中存储的水,

N 个字节数据被读取出来或将 N 个字节数据写入到文件中,这些数据就构 成了字节流。

“流”这个概念是动态的,而不是静态的。编程当中提到这个概念,一般都是与 I/O 相关,所以也经 常叫做 I/O 流;但对于目录这种特殊文件来说,这里将目录块中存储的数据称为目录流,存储了一个一个 的目录项(目录条目)。

05 struct dirent 结构体:

struct dirent { ino_t d_ino; /* inode 编号 */ off_t d_off; /* not an offset; see NOTES */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file; not supported by all filesystem types */ char d_name[256]; /* 文件名 */ 
}; 


对于 struct dirent 结构体,

我们只需要关注 d_ino d_name 两个字段即可,

分别记录了文件的 inode 编 号和文件名

每调用一次 readdir(),就会从 drip 所指向的目录流中读取下一条目录项(目录条目),

并返回 struct dirent结构体指针,指向经静态分配而得的 struct dirent 类型结构,

每次调用 readdir()都会覆盖该结构。一旦遇到 目录结尾或是出错,readdir()将返回 NULL,

针对后一种情况,还会设置 errno 以示具体错误。

那如何区别究 竟是到了目录末尾还是出错了呢,可通过如下代码进行判断:

#include <errno.h> error = 0; direntp = readdir(dirp); if (NULL == direntp) { if (0 != error) { /* 出现了错误 */ } else { /* 已经到了目录末尾 */ } } 


 这段代码很好理解,观察上面一段伪代码,error变量来自于errno头文件,

将error变量设置为0,readdir()返回空指针时证明函数执行出错,

那究竟是目录末尾还是出错了呢,如果0!=error的话,

那就证明erro值被内核设置了,证明出错了

06 rewinddir ()函数重置目录流

rewinddir()是 C 库函数,可将目录流重置为目录起点,

以便对 readdir()的下一次调用将从目录列表中的 第一个文件开始。

rewinddir 函数原型如下所示:

#include <sys/types.h> 
#include <dirent.h> void rewinddir(DIR *dirp);

 函数参数和返回值含义如下:

  1. dirp:目录句柄。
  2. 返回值:无返回值。


07 关闭目录 closedir ()函数


closedir()函数用于关闭处于打开状态的目录,同时释放它所使用的资源,其函数原型如下所示:

函数参数和返回值含义如下:

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

  1. dirp:目录句柄。
  2. 返回值:成功返回 0;失败将返回-1,并设置 errno。

测试:打印目录下的文件名与iNode

1. 打开一个目录、并将目录下的所有文件的名称 以及其对应 inode 编号打印出来。 

示例代码如下所示:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define   MY_FILE "./next"void main()
{//1创建目录/*int ret = mkdir(MY_FILE,0777);if(-1 == ret){perror("");exit(-1);}
*///2打开目录文件DIR *fdir;fdir = opendir(MY_FILE);if(NULL == fdir){perror("opendir");}int fd1 = open("./next/test.c", O_RDWR|O_CREAT, 0777);if(-1 == fd1){perror("");}//3目录文件里面的文件以及inode编号errno = 0;struct dirent *ret1 ; while(NULL != ( ret1 = readdir(fdir))){printf("inode:%ld        name:%s \n",ret1->d_ino,ret1->d_name);}if(NULL == ret1){if (errno != 0){puts("读取目录文件出错\n");}else{puts("readdir succeed\n");}}//4关闭目录文件closedir(fdir);
}

由此可知,示例代码 能够将next目录下的所有文件全部扫描出来,打印出它们的名字以及 inode节点。

08 getcwd() 函数当前工作目录

来获取进程的当前工作目录

如下所示:

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

函数参数和返回值含义如下:

  1. buf:getcwd()将内含当前工作目录绝对路径的字符串存放在 buf 缓冲区中。
  2. size:缓冲区的大小,分配的缓冲区大小必须要大于字符串长度,否则调用将会失败。
  3. 返回值:如果调用成功将返回指向 buf 的指针,失败将返回 NULL,并设置 errno。

Tips:若传入的 buf 为 NULL,且 size 为 0,则 getcwd()内部会按需分配一个缓冲区,并将指向该缓冲区 的指针作为函数的返回值,为了避免内存泄漏,调用者使用完之后必须调用 free()来释放这一缓冲区所占内 存空间。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>void main()
{char *str = getcwd(NULL,0);printf("%s ",str);free(str);
}

09 改变当前工作目录chdir()和 fchdir()

系统调用 chdir()和 fchdir()可以用于更改进程的当前工作目录

chdir()和 fchdir()函数原型:

#include <unistd.h> int chdir(const char *path); 
int fchdir(int fd); 

函数参数和返回值含义如下:

  1. path:将进程的当前工作目录更改为 path 参数指定的目录,可以是绝对路径、也可以是相对路径,指定的目录必须要存在,否则会报错。
  2. fd:将进程的当前工作目录更改为 fd 文件描述符所指定的目录(譬如使用 open 函数打开一个目录)。
  3. 返回值:成功均返回 0;失败均返回-1,并设置 errno。

此两函数的区别在于,指定目录的方式不同,

chdir()是以路径的方式进行指定,

而 fchdir()则是通过文件 描述符,文件描述符可调用 open()打开相应的目录时获得。

6.2 代码测试

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>void main()
{char *str = NULL ;str = getcwd(NULL,0);printf("%s\n ",str);free(str);/* 更改进程的当前工作目录 */ int ret = chdir("/home/chen/"); if (-1 == ret) { perror("chdir error"); exit(-1); } str = getcwd(NULL,0);printf("%s\n ",str);free(str);
}

 10 remove 函数删除文件

remove()是一个 C 库函数,用于移除一个文件或空目录,其函数原型如下所示:

函数原型:

#include <stdio.h> int remove(const char *pathname); 

使用该函数需要包含 C 库函数头文件。

函数参数和返回值含义如下:

  1. pathname:需要删除的文件或目录路径,可以是相对路径、也可是决定路径。
  2. 返回值:成功返回 0;失败将返回-1,并设置 errno。

pathname 参数指定的是一个非目录文件,那么 remove()去调用 unlink(),

如果 pathname 参数指定的是 一个目录,那么 remove()去调用 rmdir()。
与 unlink()、rmdir()一样,remove()不对软链接进行解引用操作,

若 pathname 参数指定的是一个软链接 文件,

则 remove()会删除链接文件本身、而非所指向的文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/205220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于深度学习的遥感图像变化差异可视化系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 遥感图像变化差异可视化是遥感图像处理和分析的重要研究领域之一。随着遥感技术的快速发展和遥感数据的广泛应用&#xff0c;遥感图像的获取和处理变得越来越容易…

python-比较Excel两列数据,并分别显示差异

利用 openpyxl 模块&#xff0c;操作Excel&#xff0c;比较Excel两列数据&#xff0c;并分别显示差异 表格数据样例如下图 A&#xff0c;B两列是需要进行比较的数据&#xff08;数据源为某网站公开数据&#xff09;&#xff1b;C&#xff0c;D两列是比较结果的输出列 A&#…

小白学习java理解栈手写栈——第四关(青铜挑战)

内容1.理解栈的基本特征2.理解如何使用数组来构造栈3.理解如何使用链表来构造栈 1.栈的基础知识 1.1栈的特征 栈和队列是比较特殊的线性表&#xff0c;又称为访问受限的线性表。栈是很多表达式、符号等运算的基础&#xff0c;也是递归的底层实现&#xff0c;理论上递归能做的…

Linux 防病毒软件:CentOS有哪些付费的防病毒软件

CentOS是一个基于开源的Linux发行版,通常不像Windows那样普遍需要使用付费的防病毒软件。大多数Linux系统侧重于使用开源和免费的安全工具来保护系统。一些常见的免费和开源的防病毒软件和安全工具包括ClamAV、Sophos Antivirus for Linux、rkhunter、chkrootkit等。 如果你非…

[数据集][目标检测]拉横幅识别横幅检测数据集VOC+yolo格式1962张1类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1962 标注数量(xml文件个数)&#xff1a;1962 标注数量(txt文件个数)&#xff1a;1962 标注类别数&a…

探索Scrapy-spider:构建高效网络爬虫

Spider简介 Scrapy中的Spider是用于定义和执行数据抓取逻辑的核心组件。Spider负责从指定的网站抓取数据&#xff0c;并定义了如何跟踪链接、解析内容以及提取数据的规则。它允许您定制化地指定要抓取的网站、页面和所需的信息。Spider的作用是按照预定的规则爬取网页&#xf…

边缘计算与人工智能的融合

随着物联网技术的迅猛发展&#xff0c;大量设备和传感器开始连接至互联网&#xff0c;产生了海量的数据。传统的云计算模式往往无法满足对数据实时性和隐私保护的需求&#xff0c;而边缘计算技术的兴起为解决这一难题提供了新的思路。边缘计算将数据处理和分析的功能下沉至数据…

产品成本收集器流程演示

感谢大佬的文章&#xff0c;我只是一个翻译搬运工&#xff0c;原文地址&#xff1a;产品成本收集器 概述 SAP 令人兴奋的部分之一是它在不同操作模块之间的集成程度。使用产品成本收集器来跟踪生产就是一个很好的例子。在本博客中&#xff0c;我计划遵循产品成本收集器流程&a…

JAVA刷题之数组的总结和思路分享

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

C语言第十六集(前)

1.关于那个整形存储入char的 是先取好补码,再截断 例: 2.%u是以十进制的形式打印无符号整数 3.注意(背):存储的char类型变量的补码为10000000的直接解析为-128 4.signed char 类型的变量取值范围是-128~127 5.unsigned char 类型的变量取值范围是0~255 6.有符号类型的变量…

2023.12.6 关于 Spring Boot 事务的基本概念

目录 事务基本概念 前置准备 Spring Boot 事务使用 编程式事务 声明式事务 Transactional 注解参数说明 Transational 对异常的处理 解决方案一 解决方案二 Transactional 的工作原理 面试题 Spring Boot 事务失效的场景有那些&#xff1f; 事务基本概念 事务指一…

如何解决5G基站高能耗问题?

安科瑞 须静燕 截至2023年10月&#xff0c;我国5G基站总数达321.5万个&#xff0c;占全国通信基站总数的28.1%。然而&#xff0c;随着5G基站数量的快速增长&#xff0c;基站的能耗问题也逐渐日益凸显&#xff0c;基站的用电给运营商带来了巨大的电费开支压力&#xff0c;降低5…

vue项目配置多个代理

在本地.env文件配置本地/测试/预发/正式 路径&#xff1a; 在vue.config.js 里面配置&#xff1a; module.exports defineConfig({transpileDependencies: false,lintOnSave: false,outputDir: process.env.VUE_APP_DIST,publicPath: /,css: {loaderOptions: {postcss: {// p…

Motion Plan之轨迹生成代码实现 (1)

Motion Plan之搜索算法笔记Motion Plan之基于采样的路径规划算法笔记Motion Plan之带动力学约束路径搜索 Motion Plan之轨迹生成笔记文章开始前先回顾下上次的带约束的轨迹生成&#xff0c;轨迹生成本质就是曲线拟合。曲线拟合常用的方法有&#xff1a;多项式、贝赛尔曲线、三…

CPU密集型和IO密集型与CPU内核之间的关系

CPU密集型和IO密集型与CPU内核之间的关系 一、CPU密集型 介绍 CPU密集型&#xff0c;也叫计算密集型&#xff0c;是指需要大量CPU计算资源&#xff0c;例如大量的数学运算、图像处理、加密解密等。这种类型的任务主要依赖于CPU的计算能力&#xff0c;会占用大量的CPU时间片&am…

vcomp140.dll文件丢失解决方法分享:三种亲测有效方案

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll丢失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;vcomp140.dll丢失怎样修复呢&#xff1f;本文将详细介绍解决这…

网工内推 | 国企网工、运维,厂商认证优先,13薪,带薪年假

01 中百集团 招聘岗位&#xff1a;运维工程师 职责描述&#xff1a; 1、对集团内使用云计算架构&#xff08;Kubernetes&#xff09;的系统进行规划、运维及管理相关工作。 2、对集团数据中心系统的大数据基础架构&#xff08;Cloudera Distribution Hadoop&#xff09;的规划…

打补丁,生成.diff文件

作者&#xff1a;爱塔居 文章目录 目录 前言 步骤 一、在根目录上&#xff0c;输入添加指令 二、输入修改内容指令 三、生成补丁 前言 自己的理解&#xff0c;仅供参考&#xff0c;欢迎指正。 补丁的话&#xff0c;在我看来就是方便评审&#xff0c;更方便看修改代码吧。 步骤…

Python-关系运算符详解

关系运算符&#xff1a;比较两个操作数的大小或者相等关系 < > ! 1、关系运算符的关系表达式返回值是布尔类型bool 成立就是真&#xff0c;即1&#xff1b;不成立就是假&#xff0c;即0 2、关系运算符还可以比较字符 字符根据字典序比较&#xff0c;先看首字母在…