Linux下目录文件的操作(opendir,readdir,closedir) 以及DIR,dirent,stat等结构体详解

2023-05-16

From:http://blog.chinaunix.net/uid-27213819-id-3810699.html

注:为什么要说 目录文件?其实在linux中 目录也是一种 文件,只是它的内容是上级的 目录和当前 目录下的 文件信息等,详情可以看看相关深入的书籍


opendir(打开目录

 
相关函数open,readdir,closedir,rewinddir,seekdir,telldir,scandir
表头文件#include<sys/types.h>
#include<dirent.h>
定义函数DIR * opendir(const char * name);
函数说明opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。
返回值成功则返回DIR* 形态的目录流,打开失败则返回NULL。
错误代码EACCESS 权限不足
EMFILE 已达到进程可同时打开的文件数上限。
ENFILE 已达到系统可同时打开的文件数上限。
ENOTDIR 参数name非真正的目录
ENOENT 参数name 指定的目录不存在,或是参数name 为一空字符串。
ENOMEM 核心内存不足。


readdir(读取目录


相关函数open,opendir,closedir,rewinddir,seekdir,telldir,scandir
表头文件#include<sys/types.h>
#include<dirent.h>
定义函数struct dirent * readdir(DIR * dir);
函数说明readdir()返回参数dir目录流的下个目录进入点。
结构dirent定义如下
struct dirent
{
    ino_t                 d_ino;
    ff_t                   d_off;
    signed short int d_reclen;
    unsigned char   d_type;
    har                   d_name[256];
};
d_ino      此目录进入点的inode
d_off       目录文件开头至此目录进入点的位移
d_reclen d_name的长度,不包含NULL字符
d_type    d_name 所指的文件类型
d_name  文件
返回值成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。
附加说明EBADF参数dir为无效的目录流。


closedir(关闭目录

 
相关函数opendir
表头文件#include<sys/types.h>
#include<dirent.h>
定义函数int closedir(DIR *dir);
函数说明closedir()关闭参数dir所指的目录流。
返回值关闭成功则返回0,失败返回-1,错误原因存于errno 中。
错误代码EBADF 参数dir为无效的目录
范例参考readir()。


http://www.liweifan.com/2012/05/13/linux-system-function-files-operation/

最近在看Linux下文件操作相关章节,遇到了这么几个结构体,被搞的晕乎乎的,今日有空,仔细研究了一下,受益匪浅。

首先说说DIR这一结构体,以下为DIR结构体的定义:

  1. struct __dirstream
  2. {
  3.     void     *__fd;
  4.     char     *__data;
  5.     int        __entry_data;
  6.     char     *__ptr;
  7.     int       __entry_ptr;
  8.     size_t  __allocation;
  9.     size_t  __size;
  10.     __libc_lock_define (, __lock) 
  11. };
  12.       
  13. typedef struct __dirstream DIR;

DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息(摘自《UNIX环境高级编程(第二版)》)。函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:

  1. struct dirent *readdir(DIR *dp);
  2. void rewinddir(DIR *dp);
  3. int  closedir(DIR *dp);
  4. long telldir(DIR *dp);
  5. void seekdir(DIR *dp, long loc);

关于DIR结构,我们知道这么多就可以了,没必要去再去研究他的结构成员。

接着是dirent结构体,首先我们要弄清楚目录文件(directory file)的概念:这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针(摘自《UNIX环境高级编程(第二版)》)。从定义能够看出,dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文件,这就是证据。以下为dirent结构体的定义:

 

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

从上述定义也能够看出来,dirent结构体存储的关于文件的信息很少,所以dirent同样也是起着一个索引的作用,如果想获得类似ls -l那种效果的文件信息,必须要靠stat函数了。

通过readdir函数读取到的文件名存储在结构体dirent的d_name成员中,而函数

int stat(const char *file_name, struct stat *buf);

的作用就是获取文件名为d_name的文件的详细信息,存储在stat结构体中。以下为stat结构体的定义:

  1. struct stat {
  2.             mode_t st_mode;     //文件访问权限
  3.             ino_t  st_ino;      //索引节点号
  4.             dev_t  st_dev;      //文件使用的设备号
  5.             dev_t  st_rdev;     //设备文件的设备号
  6.             nlink_t st_nlink;   //文件的硬连接数
  7.             uid_t  st_uid;      //所有者用户识别号
  8.             gid_t  st_gid;      //组识别号
  9.             off_t  st_size;     //以字节为单位的文件容量
  10.             time_t st_atime;    //最后一次访问该文件的时间
  11.             time_t st_mtime;     //最后一次修改该文件的时间
  12.             time_t st_ctime;     //最后一次改变该文件状态的时间
  13.             blksize_t st_blksize; //包含该文件的磁盘块的大小
  14.             blkcnt_t st_blocks;    //该文件所占的磁盘块
  15. };


这个记录的信息就很详细了吧,呵呵。

最后,总结一下,想要获取某目录下(比如a目下)b文件的详细信息,我们应该怎样做?
首先
,我们使用opendir函数打开目录a,返回指向目录a的DIR结构体c。
接着
,我们调用readdir(c)函数读取目录a下所有文件(包括目录),返回指向目录a下所有文件的dirent结构体d。
然后,我们遍历d,调用stat(d->name,stat *e)来获取每个文件的详细信息,存储在stat结构体e中。

总体就是这样一种逐步细化的过程,在这一过程中,三种结构体扮演着不同的角色。

下面我们开发一个小程序,这个程序有一个参数.如果这个参数是一个文件名,我们输出这个文件的大小和最后修改的时间,如果是一个目录我们输出这个目录下所有文件的大小和修改时间.

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <dirent.h>
  7. #include <time.h>

  8. static int get_file_size_time(const char *filename) {
  9.     struct stat statbuf;
  10.     if (stat(filename, &statbuf) == -1) {
  11.         printf("Get stat on %s Error:%s\n",
  12.                 filename, strerror(errno));
  13.         return (-1);
  14.     }
  15.     if (S_ISDIR(statbuf.st_mode))return (1);
  16.     if (S_ISREG(statbuf.st_mode))
  17.         printf("%s size:%ld bytes\tmodified at %s",
  18.             filename, statbuf.st_size, ctime(&statbuf.st_mtime));
  19.     return (0);
  20. }

  21. int main(int argc, char **argv) {
  22.     DIR *dirp;
  23.     struct dirent *direntp;
  24.     int stats;
  25.     char buf[80];
  26.     if (argc != 2) {
  27.         printf("Usage:%s filename\n\a", argv[0]);
  28.         exit(1);
  29.     }
  30.     if (((stats = get_file_size_time(argv[1])) == 0) || (stats == -1))exit(1);
  31.     if ((dirp = opendir(argv[1])) == NULL) {
  32.         printf("Open Directory %s Error:%s\n",
  33.                 argv[1], strerror(errno));
  34.         exit(1);
  35.     }
  36.     while ((direntp = readdir(dirp)) != NULL){
  37.         sprintf(buf,"%s/%s",argv[1],direntp->d_name);
  38.         if (get_file_size_time(buf) == -1)break;
  39.     }
  40.     closedir(dirp);
  41.     exit(1);
  42. }
  43.         

//判断一个目录文件是否存在可以用c语言库里的Access函数

int _access( const char *path, int mode );

Return Value

Each of these functions returns 0 if the file has the given mode. The function returns –1 if the named file does not exist or is not accessible in the given mode; in this case, errno is set as follows:

EACCES

Access denied: file’s permission setting does not allow specified access.

ENOENT

Filename or path not found.

Parameters

path

File or directory path

mode

Permission setting

Remarks

When used with files, the _access function determines whether the specified file exists and can be accessed as specified by the value of mode. When used with directories, _access determines only whether the specified directory exists; in Windows NT, all directories have read and write access.

mode Value            Checks File For 
00                              Existence only 
02                              Write permission 
04                              Read permission 
06                              Read and write permission

http://www.liweifan.com/2011/12/19/embedded-system-s3c2440-sdram-link/    s3c2440 sdram
  1. /* ACCESS.C: This example uses _access to check the
  2.  * file named "ACCESS.C" to see if it exists and if
  3.  * writing is allowed.
  4.  */

  5. #include <io.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>

  8. void main( void )
  9. {
  10.    /* Check for existence */
  11.    if( (_access( "ACCESS.C", 0 )) != -1 )
  12.    {
  13.       printf( "File ACCESS.C exists " );
  14.       /* Check for write permission */
  15.       if( (_access( "ACCESS.C", 2 )) != -1 )
  16.          printf( "File ACCESS.C has write permission " );
  17.    }
  18. }


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下目录文件的操作(opendir,readdir,closedir) 以及DIR,dirent,stat等结构体详解 的相关文章

  • Copilot:AI自动写代码,人工智能究竟还能取代什么?

    Copilot xff1a AI自动写代码 xff0c 人工智能究竟还能取代什么 xff1f 前言 在AI绘画掀起一阵热潮之后 xff0c AI写代码又逐渐进入了我们的视野 xff0c 似乎这一步我们还没想到就迅速到来了 xff0c 难道说
  • 关于SubSonic3.0生成的表名自动加复数(s)的“用户代码未处理SqlException,对象名‘xxxs‘无效”异常处理

    关于SubSonic3 0生成的表名自动加复数 xff08 s xff09 的 用户代码未处理SqlException xff0c 对象名 39 xxxs 39 无效 异常处理 参考文章 xff1a xff08 1 xff09 关于SubS
  • 互联网金融风控面试算法知识(三)

    资料来源于网络搜集和汇总 xff0c 把算法知识的总结放在业务知识后面也是为了说明实际工作业务落地应用的重要性大于算法创新 面试题依然是适用于3年经验以内的初学者 xff0c 希望大家在学习算法的同时不要一心只研究算法而脱离了业务 xff0
  • wiki树莓派安装ubuntu mate 和 ros

    两大步骤 1 安装ubuntu mate 2 安装ros 一 安装ubuntu mate 下载ubuntu mate 18 04 img 并制作系统盘 首先要说的就是树莓派支持的系统是很多样的 xff0c 但是针对ros xff0c 我们只
  • npm 的工作原理

    包 Package 和模块 Module 如何定义一个Package 满足如下条件都可以称为一个包 xff1a 一个文件夹包含应用程序 xff0c 使用package json来描述它 a 一个用gzip压缩的文件夹 xff0c 满足 a
  • 2023最全Postman安装使用详解

    一 Postman背景介绍 用户在开发或者调试网络程序或者是网页B S模式的程序的时候是需要一些方法来跟踪网页请求的 xff0c 用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具 今天给大家介绍的这款网页调试工具不仅可以
  • cmake 设置 debug release模式

    1 通过命令行的方式 cmake DCMAKE BUILD TYPE 61 Debug 2 set CMAKE BUILD TYPE Debug CACHE STRING 34 set build type to debug 34 或者 s
  • 华为笔试题(4)

    一 计算n x m的棋盘格子 xff08 n为横向的格子数 xff0c m为竖向的格子数 xff09 沿着各自边缘线从左上角走到右下角 xff0c 总共有多少种走法 xff0c 要求不能走回头路 xff0c 即 xff1a 只能往右和往下走
  • 安装RedisBloom插件

    前言 安装RedisBloom模块会遇到很多坑 xff0c 希望你不要和我一样踩的这么全 x1f60f 如果觉得编译麻烦 xff0c 我也上传了我编译的so文件 xff0c 可以直接加载使用 https download csdn net
  • ROS Catkin 教程之 CMakeLists.txt

    1 概览 CMakeLists txt 是用 CMake 构建系统构建 ROS 程序包的输入文件 任何兼容 CMake 的包都包含一个或多个 CMakeLists txt 文件 xff0c 用以描述怎样构建和安装代码 catkin 项目采用
  • Xsens Mti-g-710 IMU driver在Ubuntu18.04 ROS melodic中的安装使用

    Ubuntu18 04下安装的ROS melodic 如何使用Xsens Mti g 710 IMU driver xff1f 这里给出一个详细步骤说明 这里的IMU是USB接口 1安装 首先插入IMU的USB口 命令行运行 gt lsus
  • PYTHON -MYSQLDB安装遇到的问题和解决办法

    PYTHON MYSQLDB安装遇到的问题和解决办法 参考文章 xff1a xff08 1 xff09 PYTHON MYSQLDB安装遇到的问题和解决办法 xff08 2 xff09 https www cnblogs com gaosh
  • 位姿估计Robot_pose_efk的配置和使用

    Robot pose efk 用于融合里程计 xff0c 惯性测量单元和视觉里程计的传感器输出 xff0c 从而减少测量中的总体误差 了解ROS的robot pose ekf软件包中扩展卡尔曼滤波器的用法 xff1a robot pose
  • linux录屏和截图软件

    linux下的录屏和截图软件有很多 xff0c kazam集成了录屏和截图两个功能 xff0c 而且十分轻量级 xff0c 比较好用 如果是在VirtualBox虚拟机中跑linux的话 xff0c virtualbox本身就提供录屏和截图
  • APM 学习 6 --- ArduPilot 线程

    ArduPilot 学习之路 6 xff0c 线程 英文原文地址 xff1a https ardupilot org dev docs learning ardupilot threading html 理解 ArduPilot 线程 线程
  • nginx 配置多个vue,环境部署

    1 最近项目要上线 xff0c 需要通过nginx作为代理 xff0c 要发布2个VUE前端项目 xff0c 记录一下nginx conf配置文件 亲自验证 xff0c 特此记录一下 xff0c 希望能帮助向我一样 小白的人 user ro
  • freertos源码分析(1)--初始篇

    代码下载地址 xff1a https www freertos org 部分转载参考 FreeRTOS基础知识 xff1a RTOS全称为 xff1a Real Time OS xff0c 就是实时操作系统 xff0c 强调的是 xff1a
  • nginx服务占用百分之百

    一 当nginx达到100 时 xff0c 也就是服务器负载突然上升 1 利用top命令查看cpu使用率较高的php cgi进程 PID USER PR NI VIRT RES SHR S CPU MEM TIME 43 COMMAND 1
  • Gazebo教程(使用roslaunch 启动Gazebo,world以及urdf模型)

    Gazebo教程 xff08 使用roslaunch 启动Gazebo xff0c world以及urdf模型 xff09 关于如何学习ROS可以参考古月居的这篇文章 1 https www zhihu com question 35788
  • dispatch_queue_create---创建队列

    dispatch queue create span class hljs keyword const span span class hljs keyword char span label dispatch queue attr t a

随机推荐

  • Java多种方式解决生产者消费者问题(十分详细)

    一 问题描述 生产者消费者问题 xff08 Producer consumer problem xff09 xff0c 也称有限缓冲问题 xff08 Bounded buffer problem xff09 xff0c 是一个多线程同步问题
  • Http协议WWW-Authenticate

    HTTP协议有一个叫WWW Authenticate的头字段 xff0c 可以用于实现登录验证 它是在RFC 2617中定义的 当服务器接收到一个request xff0c 并在实现下面的代码 xff1a br http response
  • Android 运行时注解

    编译时注解点击此处 xff5e xff5e xff5e 运行时注解 以 64 BindView 为例 下面是实现步骤 新建一个 apt annotation 的 java library xff0c 然后在库中新建一个注解 xff0c 传入
  • 使用k-近邻算法识别手写数字。

    在之前的文章中介绍了k 近邻算法的原理知识并且用Python实现了一个分类器 xff0c 而且完成了一个简单的优化约会网站配对效果的实例 在 机器学习实战 中有关kNN的后一部分内容就是一个手写识别系统 xff0c 可以识别手写的0 9的数
  • 在Ubuntu14.04不能添加PPA源到apt源的问题解决方法

    在Ubuntu14 04使用apt get 更新Git 时 xff0c 需要更新apt源 xff0c 添加一个带有最新Git的源 xff0c 如下命令 xff1a sudo add apt repository ppa git core p
  • 单片机的操作本质【以STM32系列为例】

    单片机的操作本质 摘要寄存器的本质单片机的操作本质操作寄存器的方法 摘要 本文档是笔者学习野火F103视频 课时5 至 课时7 的总结 视频链接 xff1a https study 163 com course introduction 1
  • 《视觉SLAM进阶:从零开始手写VIO》第一讲作业

    目录 1 视觉与IMU融合之后有何优势 xff1f 2 有哪些常见的视觉 43 IMU融合方案 xff1f 有没有工业界应用的例子 xff1f 3 在学术界 xff0c VIO研究有哪些新进展 xff1f 有没有将学习方法应用到VIO的例子
  • GPS坐标与UTM坐标的转换

    1 简介 1 1 消息 gps common定义了两个通用消息 xff0c 供GPS驱动程序输出 xff1a gps common GPSFix和gps common GPSStatus 在大多数情况下 xff0c 这些消息应同时发布 xf
  • NVIDIA Jetson TX2使用笔记(一):开机设置

    0 写在前面 由于项目需要 xff0c 使用 NVIDIA Jetson TX2作为硬件开发平台 xff0c 在此记录使用方法和遇到的问题 NVIDIA Jetson TX2是英伟达的嵌入式开发套件 xff0c 可以进行视觉计算 xff0c
  • ORB-SLAM2的安装与运行

    0 背景简介 ORB SLAM是西班牙Zaragoza大学的Raul Mur Artal编写的视觉SLAM系统 他的论文 ORB SLAM a versatile andaccurate monocular SLAM system 34 发
  • Ubuntu14.04升级cmake版本的方法

    在Ubuntu14 04用以下命令默认安装的cmake版本为2 8 x xff0c 有时我们需要更高版本的cmake xff0c 所以需要升级 span class hljs built in sudo span apt get insta
  • 在TX2上配置ORB-SLAM2错误总结

    Pangolin 错误描述 usr lib gcc aarch64 linux gnu 5 aarch64 linux gnu libGL so undefined reference to 96 drmFreeDevice 解决方法 cd
  • docker镜像迁移/移植

    docker镜像迁移 移植 或者docker save 镜像名 版本号 o 路径 保存的包名 tar 通过这两个命令保存保存镜像 xff0c 下载到本地再上传到其他服务器 然后通过docker load lt 保存的包名 tar 完成镜像移
  • 安装并运行VINS-Mono

    0 A Robust and Versatile Monocular Visual Inertial State Estimator VINS Mono是单目视觉惯性系统的实时SLAM框架 它使用基于优化的滑动窗口配方来提供高精度的视觉惯性
  • 使用小觅双目-惯性相机运行VINS-Mono

    步骤 1 下载相机驱动MYNT EYE SDK 2 xff0c 然后make ros xff08 注意 xff1a 前面的Ubuntu安装也要操作 xff09 xff1b 2 安装VINS Mono xff1b 3 在MYNT EYE VI
  • 在TX2上安装VIINS-Mono——问题总结

    1 ceres solver 我们一般通过以下命令安装Eigen xff1a sudo apt get install libeigen3 dev 默认安装在 usr include eigen3 在CMakeList txt中一般用以下语
  • LeGO-LOAM初探:原理,安装和测试

    前言 最近要搞3D激光SLAM xff0c 先后测试了Autoware xff0c cartographer xff0c loam和LeGO LOAM 今天就带来LeGO LOAM的使用体验 Github xff1a https githu
  • IMU噪声标定——加速度计和陀螺仪的白噪声和零偏不稳定性

    前言 imu utils是一个用于分析IMU性能的ROS工具包 参考资料 Allan Variance Noise Analysis for Gyroscopesvectornav gyroscopeAn introduction to i
  • TF坐标变换

    文章目录 TF坐标变换TF功能包TF工具乌龟例程中的TF创建TF广播器创建TF监听器实现乌龟跟随运动 存在的问题总结参考 TF坐标变换 坐标变换是机器人学中一个非常基础 xff0c 同时也是非常重要的概念 机器人本体和机器人的工作环境中往往
  • Linux下目录文件的操作(opendir,readdir,closedir) 以及DIR,dirent,stat等结构体详解

    From http blog chinaunix net uid 27213819 id 3810699 html 注 xff1a 为什么要说 目录文件 xff1f 其实在linux中 目录也是一种 文件 xff0c 只是它的内容是上级的