linux下对目录文件进行操作(打开目录,读取目录项,关闭目录),进入目录的函数chdir,七篇文件I/O文章小结

embedded/2024/12/23 7:37:44/

目录文件介绍

目录也是一种文件,因此操作流程与普通文件类似,有诸如打开、关闭、定位等概念,但目录是一种特殊的文件,目录存储的数据的最小单位并不是字符,而是目录项。这使得目录跟普通文件又有区别。目录项指的是结构体struct dirent{},其内部保存的是文件的名称、idnode节点号等基本信息,不包含文件具体内容。

// 目录项结构体
struct dirent
{ino_t  d_ino;       /* i-node节点号 */char   d_name[256]; /* 文件名 */
};

这个结构体中可能还会有其他的属性,但是我们一般用不到,并且不同电脑环境下结构体内部字段有些差别,但是i-node节点号和文件名这两个字段一定都存在。

这里的idnode节点号对应的是一个idnode结构体变量,保存着文件的基本信息如文件大小、权限、所有者、所属组、创建时间、修改时间等,所以这个idnode号可以用来进一步查询文件的详细信息

opendir,readdir,closedir(打开,读取,关闭目录)

与文件操作类似,要操作目录,首先是打开目录获取代表目录的“目录指针”,然后读取目录的基本单元“目录项”,最后关闭目录指针释放资源。操作函数如下:

示例代码:

int main(void)
{// 打开目录,获取目录指针DIR *dp = opendir("a");// 读取每个目录项,并输出各个文件的名称struct dirent *ep;while(1){ep = readdir(dp);// 读完了if(ep == NULL){break;}printf("%s\n", ep->d_name);}
}

注意:

这里readdir函数每次读取正确的时候返回的是文件项指针,所以这里我们要使用指针变量来保存循环拿到的文件项指针。

完整代码示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<strings.h>
int main(int argc, char **argv) {if(argc!=2){printf("%s","需要提供目录\n");exit(0);}
//检测文件类型,只有目录文件才能输出目录项struct stat file_stat;bzero(&file_stat,sizeof(stat));stat(argv[1],&file_stat);if(!S_ISDIR(file_stat.st_mode)){printf("%s is NoT directory.n", argv[1]);exit(0);}//打开目录文件DIR *file_dp = opendir(argv[1]);if(file_dp == NULL){perror("opendir()failed");exit(0);}//读取目录项struct dirent *ep;while(1){ep=readdir(file_dp);if(ep==NULL){break;}printf("%s\n",ep->d_name);}return 0;
}

一个理解上易错点

打开目录并不意味着进入目录,打开目录的时候当前的进程路径并没有切换到目录文件内部,即 DIR *dp = opendir("a");这行代码并没有让我们进入到a目录里面(没有cd a),我们当前的工作路径还是在目录文件所处父目录的路径。

那我们如何来直观地感受这一点呢?上面我们的例子中输出了目录文件a下的所有文件名称,那现在我们像下图一般,在输出文件名称基础上输出文件大小。这就需要用到获取文件属性的知识,通过提供文件名,通过stat函数获取文件大小。代码如下

错误示范 

我们会发现事与愿违了,不能正确输出文件的大小,原因是stat函数找不到这些文件。我们这里提供给stat函数的文件名称都是a.txt这样形式的,是进入目录文件后才可直接看到的名称,但我们打开目录并不意味着进入了目录,我们实际上根本没有进去到目录里面,所以在外面是看不到a.txt这个名字的,想要看到的话需要添加这个文件的目录前缀,比如:linux_share/a.txt,将这个字符串提供给stat函数才能得到文件属性。

这当然是个方法,可以利用字符串拼接的方式将完整的文件名称传给stat函数,但是有点过于麻烦了。我们上面的代码会出问题的原因是当前的进程路径并没有切换到目录文件内部,我们只需要进入目录文件就行了,写cd语句肯定是不行的,这里的chdir函数可以帮助我们在代码中实现cd的功能,只需要在代码中加入这一行chdir改变进程路径代码就可以了,是不是很简便。

 正确示范

只需要在这里打开目录文件的时候顺便进入目录文件。就能实现将目录下的文件名称和文件大小都打印出来。真正进入目录的函数是chdir,其实就是和命令行中的cd功能一样。

chdir函数详解 

文件I/O文章小结

前言:截至到今天,文件I/O系列文章已经写了七篇文章,这七篇文章带着我们从系统I/O函数——>标准I/O函数,随后我们又了解了linux中文件的存储和属性相关信息,知道了如何查看文件的各种属性,最后我们简单地谈了一下linux下如何对目录文件内容进行访问。

展望未来:接下来的文章将会继续这一个专题,只不过我们要开始联系实际,使用我们开发板来巩固我们对这些内容的学习。

标准I/O

对于我们的普通文件来说我们既可以使用系统I/O和标准I/O对文件进行操作,我们推荐使用标准I/O对普通文件操作,因为多了系统的缓冲区,减少了系统I/O调用次数,操作效率提高了。但是标准I/O一般就是简化了我们对于普通文件的操作(包含二进制文件)。对于其他类型的文件我们一帮更加推荐使用系统。

系统I/O

对于FIFO 文件、符号链接、字符设备文件、块设备文件和套接字,我们推荐使用系统I/O和一些特定函数对这些文件进行操作。不同类型文件有着对应特定函数。比如说对于LCD屏幕(通常属于字符设备文件),我们常常用open和close系统I/O打开关闭文件,再配合上特定的mmap函数对设备文件进行操作。(如 open, read, write, ioctl

文件特定操作函数

对于目录文件来说我们用到的通常就是特定的函数对其进行操作

  • opendir:打开一个目录,并返回一个指向 DIR 结构的指针。
  • readdir:从目录流中读取下一个目录项。
  • closedir:关闭目录流。
  • mkdir:创建一个新目录。
  • rmdir:删除一个空目录。

http://www.ppmy.cn/embedded/97912.html

相关文章

解决Vue3+Ts打包项目时会生成很多的map文件

正常打包会生成.js和.map文件 怎么去解决它呢&#xff1f; 正常来说我们会在vite.config.ts配置我们的项目打包方式&#xff0c;如下&#xff1a;&#xff08;我这里的target&#xff1a;es2022是为了支持模块中顶层await的使用&#xff09; // Vite 配置文件 export default…

Qt/QML学习-StackView

QML学习 StackView例程视频讲解代码 main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15Window {width: 640height: 480visible: truetitle: qsTr("StackView")StackView {id: stackViewanchors.fill: parent// 背景视图back…

Autodesk Maya 2019 for Mac/Win:专业三维动画制作软件的巅峰之作

Autodesk Maya 2019是一款世界顶级的三维动画制作软件&#xff0c;专为Mac和Windows系统打造&#xff0c;广泛应用于影视广告、角色动画、电影特技等专业领域。其强大的功能和灵活的工具集&#xff0c;使得用户能够高效地完成复杂的三维建模、动画设计、特效制作及高质量渲染等…

机器学习(2)-- KNN算法之手写数字识别

文章目录 KNN算法数字识别训练模型完整代码展示 测试模型测试新的数据 总结 KNN算法 KNN&#xff08;K-Nearest Neighbor&#xff0c;K最近邻&#xff09;算法是一种用于分类和回归的非参数统计方法&#xff0c;尤其在分类问题中表现出色。在手写数字识别领域&#xff0c;KNN算…

Apache HOP (Hop Orchestration Platform) VS Data Integration (通常被称为 Kettle)

Apache HOP (Hop Orchestration Platform) 和 Data Integration (通常被称为 Kettle) 都是强大的 ETL (Extract, Transform, Load) 工具&#xff0c; 它们都由 Hitachi Vantara 开发和支持。尽管它们有着相似的目标&#xff0c;即帮助用户进行数据集成任务&#xff0c;但它们在…

差分法(Differencing),多变量差分对多个时间序列进行联合分析

介绍 差分法&#xff08;Differencing&#xff09;是时间序列分析中的一种重要技术&#xff0c;主要用于使非平稳时间序列变得平稳&#xff0c;以便能够应用诸如ARIMA&#xff08;AutoRegressive Integrated Moving Average&#xff09;模型等线性模型。非平稳时间序列通常具有…

二:《Python基础语法汇总》— 条件判断与循环结构

一&#xff1a;条件判断 1.程序执行的三大流程&#xff1a; ​ 顺序流程&#xff1a;无缩进代码&#xff0c;从上往下依次执行 ​ 分支流程&#xff1a;选择性执行某块代码&#xff0c;或跳过某行代码去执行&#xff0c;与缩进&#xff08;TAB&#xff09;有关 ​ 循环流程&…

超实用的短链接使用指南

当你突然灵感爆棚&#xff0c;有一个自认为能火出地球的创意推广&#xff0c;正准备把链接分享出去的时候&#xff0c;可不能让那些长长的链接坏了事&#xff01; 链接太长&#xff0c;会让人觉得不安全可靠&#xff0c;大大影响点击量&#xff1b; 字节太多&#xff0c;短信…