前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >文件目录 (一).stat(2)

文件目录 (一).stat(2)

作者头像
franket
发布2021-09-16 09:48:00
发布2021-09-16 09:48:00
58900
代码可运行
举报
文章被收录于专栏:技术杂记技术杂记
运行总次数:0
代码可运行
  • opendir
  • closedir
  • readdir
  • rewinddir

除了 opendir 接收一个文件名字符串,返回一个 DIR 型指针,其它几个函数的参数都是接受一个 DIR 型的指针


dirent

代码中有一个这样的定义

代码语言:javascript
代码运行次数:0
运行
复制
struct dirent *de=NULL;

dirent 是一种新的结构体

在头文件中有所定义

代码语言:javascript
代码运行次数:0
运行
复制
emacs@ubuntu:/usr/include$ grep dirent dirent.h  | head -n 3
 *	POSIX Standard: 5.1.2 Directory Operations	<dirent.h>
/* This file defines `struct dirent'.
#include <bits/dirent.h>
emacs@ubuntu:/usr/include$ 

从中可知是定义到了 bits/dirent.h

代码语言:javascript
代码运行次数:0
运行
复制
#ifndef _DIRENT_H
# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
#endif

struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino; //索引节点号, inode number
    __off_t d_off; //在目录文件中的偏移,offset to this dirent  
#else
    __ino64_t d_ino; 
    __off64_t d_off;
#endif
    unsigned short int d_reclen;  
    unsigned char d_type; //文件类型, the type of d_name
    char d_name[256];           /* We must not include limits.h! */ //文件名,最长255字符 file name (null-terminated) 
  };

其中提供的信息也比较少,但是从中我们可以看出,文件名最大长度只能为255的原因 ,因为系统只给了256个字符的长度用来存储文件名

总体来看,这个目录条目结构体,也是一个简略的索引


stat

代码中有一个这样的定义

代码语言:javascript
代码运行次数:0
运行
复制
struct stat fs;

stat 是一种新的结构体

在头文件中有所定义

代码语言:javascript
代码运行次数:0
运行
复制
emacs@ubuntu:/usr/include$ grep stat sys/stat.h | grep include
#include <bits/stat.h>
emacs@ubuntu:/usr/include$ 

详细信息在 bits/stat.h

代码语言:javascript
代码运行次数:0
运行
复制
#ifndef _SYS_STAT_H
# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
#endif


struct stat
  {
    __dev_t st_dev;		/* Device.  */  //文件使用的设备号
#if __WORDSIZE == 32
    unsigned short int __pad1;
#endif
#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
    __ino_t st_ino;		/* File serial number.	*/  //索引节点号
#else
    __ino_t __st_ino;			/* 32bit file serial number.	*/
#endif  //索引节点号
#else
#if __WORDSIZE == 32
    __mode_t st_mode;			/* File mode.  */  //文件访问权限  
    __nlink_t st_nlink;			/* Link count.  */  //文件的硬连接数
#else
    __nlink_t st_nlink;		/* Link count.  */  //文件的硬连接数
    __mode_t st_mode;		/* File mode.  */  //文件访问权限
#endif
    __uid_t st_uid;		/* User ID of the file's owner.	*/  //所有者用户识别号
    __gid_t st_gid;		/* Group ID of the file's group.*/  //组识别号
#if __WORDSIZE == 64
    int __pad0;
#endif
    __dev_t st_rdev;		/* Device number, if device.  */
#if __WORDSIZE == 32
    unsigned short int __pad2;
#endif
#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
    __off_t st_size;			/* Size of file, in bytes.  */  //以字节为单位的文件容量   
#else
    __off64_t st_size;			/* Size of file, in bytes.  */  //以字节为单位的文件容量   
#endif
    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */ //该文件所占的磁盘块   
#else
    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
#endif
#ifdef __USE_MISC
    /* Nanosecond resolution timestamps are stored in a format
       equivalent to 'struct timespec'.  This is the type used
       whenever possible but the Unix namespace rules do not allow the
       identifier 'timespec' to appear in the <sys/stat.h> header.
       Therefore we have to handle the use of this header in strictly
       standard-compliant sources special.  */
    struct timespec st_atim;		/* Time of last access.  */  //最后一次访问该文件的时间
    struct timespec st_mtim;		/* Time of last modification.  */  //最后一次修改该文件的时间 
    struct timespec st_ctim;		/* Time of last status change.  */   //最后一次改变该文件状态的时间  
# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
# define st_mtime st_mtim.tv_sec
# define st_ctime st_ctim.tv_sec
#else
    __time_t st_atime;			/* Time of last access.  */
    unsigned long int st_atimensec;	/* Nscecs of last access.  */
    __time_t st_mtime;			/* Time of last modification.  */
    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
    __time_t st_ctime;			/* Time of last status change.  */
    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
#endif
#if __WORDSIZE == 64
    long int __unused[3];
#else
# ifndef __USE_FILE_OFFSET64
    unsigned long int __unused4;
    unsigned long int __unused5;
# else
    __ino64_t st_ino;			/* File serial number.	*/
# endif
#endif
  };

这里可以获得文件的绝大部分属性信息

Tip: 头文件里有很多如下形式的条件编译,是为了进行兼容处理

代码语言:javascript
代码运行次数:0
运行
复制
#ifndef
#else
#endif

读取文件属性过程

  • 使用 opendir 函数打开一个目录文件(文件名字符串),返回一个 DIR 指针
  • 使用 readdir 函数读取 DIR 指针,返回一个 dirent 指针
  • 通过 stat 函数读取 direntP->d_name (文件名字符串),得到 stat 结构体
  • 通过 stat 结构体,获取详细属性信息

有点小复杂


总结

以下这些函数可以应对绝大部分的文件或目录属性查询需求

  • opendir
  • closedir
  • readdir
  • rewinddir
  • stat

通过各方面资料弄懂其参数的意义和返回值的类型,是熟练掌握的基础

原文地址

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • dirent
  • stat
  • 读取文件属性过程
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档