文件操作opendir()/readdir()/closedir()/stat()

linux系统编程(五):目录操作(opendirreaddirclosedirstat 1、ls的作用 ls命令主要用与输出目录相关的信息。包括当前目录包含的文件,文件的模式,所属,大小等等。 2、相关系统调用 2.1、打开一个目录opendir opendir 目标 根据目录名打开目录 头文件 #include <sys/types.h> #include <dirent.h> 函数原型 DIR *ope... 阅读详情
头文件
#include<dirent.h>

#include<sys/types.h>

在Linux下opendir()、readdir()和closedir()这三个函数主要用来遍历目录。

int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。

opendir():
函数原型:
DIR * opendir(const char* path);

打开一个目录,在失败的时候返回NULL(如果path对应的是文件,则返回NULL)
opendir函数的作用是打开一个目录并建立一个目录流。如果成功,它返回一个指向DIR结构的指针,该指针用于读取目录数据项。

opendir在失败时会返回一个空指针。注意,目录流用一个底层文件描述符来访问目录本身,所以如果打开的文件过多,opendir可能会失败。

DIR 结构体的原型为:struct_dirstream

       在linux系统中:

        typedef struct __dirstream DIR;

       struct __dirstream
       {
         void *__fd; /* `struct hurd_fd' pointer for descriptor.   */
         char *__data; /* Directory block.   */
         int __entry_data; /* Entry number `__data' corresponds to.   */
         char *__ptr; /* Current pointer into the block.   */
         int __entry_ptr; /* Entry number `__ptr' corresponds to.   */
         size_t __allocation; /* Space allocated for the block.   */
         size_t __size; /* Total valid data in the block.   */
         __libc_lock_define (, __lock) /* Mutex lock for this structure.   */
        };
readdir():
函数原型:
struct dirent * readdir(DIR * dir_handle);
本函数读取dir_handle目录下的目录项,如果有未读取的目录项,返回目录项,否则返回NULL。
循环读取dir_handle,目录和文件都读

       返回dirent结构体指针,dirent结构体成员如下,(文件和目录都读)

  struct dirent

  {

  long d_ino; /* inode number 索引节点号 */

  off_t d_off; /* offset to this dirent 在目录文件中的偏移 */

  unsigned short d_reclen; /* length of this d_name 文件名长 */

  unsigned char d_type; /* the type of d_name 文件类型 */

  char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符*/

  }

readdir函数将返回一个指针,指针指向的结构里保存着目录流drip中下一个目录项的有关资料。每调用一次readdir,就有一个文件名保存到d_name [NAME_MAX+1]中,后续的readdir调用将返回后续的目录项如果发生错误或者到达目录尾,readdir将返回NULL。POSIX兼容的系统在到达目录尾时会返回NULL,但并不改变errno的值,在发生错误时才会设置errno。

  注意,如果在readdir函数扫描目录的同时还有其他进程在该目录里创建或删除文件,readdir将不保证能够列出该目录里的所有文件(和子目录)。

  dirent结构中包含的目录数据项内容包括以下部分:

  ino_t d_ino——文件的inode节点号

  char d_name[ ]——文件的名字

  要想进一步了解目录中某个文件的详细资料,则需要使用在本章前面介绍过的stat调用。

closedir():
函数原型:

int closedir(DIR * dir_handle);

telldir函数

  telldir函数的返回值记录着一个目录流里的当前位置。你可以在随后的seekdir调用中利用这个值来重置目录扫描到当前位置

seekdir函数

  seekdir函数的作用是设置目录流dirp的目录项指针。loc的值用来设置指针位置,它应该通过前一个telldir调用获得。

最近在看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.   
  3. void rewinddir(DIR *dp);   
  4.   
  5. int closedir(DIR *dp);   
  6.   
  7. long telldir(DIR *dp);   
  8.   
  9. 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.      
  5.     off_t d_off; /* offset to this dirent 在目录文件中的偏移 */  
  6.      
  7.     unsigned short d_reclen; /* length of this d_name 文件名长 */  
  8.      
  9.     unsigned char d_type; /* the type of d_name 文件类型 */  
  10.      
  11.     char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */  
  12. }  

 

从上述定义也能够看出来,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.   
  3.         mode_t     st_mode;       //文件访问权限  
  4.   
  5.         ino_t      st_ino;       //索引节点号  
  6.   
  7.         dev_t      st_dev;        //文件使用的设备号  
  8.   
  9.         dev_t      st_rdev;       //设备文件的设备号  
  10.   
  11.         nlink_t    st_nlink;      //文件的硬连接数  
  12.   
  13.         uid_t      st_uid;        //所有者用户识别号  
  14.   
  15.         gid_t      st_gid;        //组识别号  
  16.   
  17.         off_t      st_size;       //以字节为单位的文件容量  
  18.   
  19.         time_t     st_atime;      //最后一次访问该文件的时间  
  20.   
  21.         time_t     st_mtime;      //最后一次修改该文件的时间  
  22.   
  23.         time_t     st_ctime;      //最后一次改变该文件状态的时间  
  24.   
  25.         blksize_t st_blksize;    //包含该文件的磁盘块的大小  
  26.   
  27.         blkcnt_t   st_blocks;     //该文件所占的磁盘块  
  28.   
  29.       };  

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

最后,总结一下,想要获取某目录下(比如a目下)b文件的详细信息,我们应该怎样做?

首先,我们使用opendir函数打开目录a,返回指向目录a的DIR结构体c。

接着,我们调用readdir( c)函数读取目录a下所有文件(包括目录),返回指向目录a下所有文件的dirent结构体d。

然后,我们遍历d,调用stat(d->name,stat *e)来获取每个文件的详细信息,存储在stat结构体e中。

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


三个函数介绍完了,直接来一个例子吧:
**********************************************SearchDir.c****************************************************
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
char filename[256][256];
int len = 0;
int trave_dir(char* path, int depth)
{
    DIR *d; //声明一个句柄
    struct dirent *file; //readdir函数的返回值就存放在这个结构体中
    struct stat sb;    
    
    if(!(d = opendir(path)))
    {
        printf("error opendir %s!!!/n",path);
        return -1;
    }
    while((file = readdir(d)) != NULL)
    {
        //把当前目录.,上一级目录..及隐藏文件都去掉,避免死循环遍历目录
        if(strncmp(file->d_name, ".", 1) == 0)
            continue;
        strcpy(filename[len++], file->d_name); //保存遍历到的文件名
        //判断该文件是否是目录,及是否已搜索了三层,这里我定义只搜索了三层目录,太深就不搜了,省得搜出太多文件
        if(stat(file->d_name, &sb) >= 0 && S_ISDIR(sb.st_mode) && depth <= 3)
        {
            trave_dir(file->d_name, depth + 1);
        }
    }
    closedir(d);
    return 0;
}
int main()
{
    int depth = 1;
    int i;
    trave_dir("/usr/keygoe/ini/", depth);
    for(i = 0; i < len; i++)
    {
        printf("%s/t", filename[i]);
    }
    printf("/n");
    return 0;
}

c++赋值(赋值为函数返回值)语句的返回值问题 不知道为什么,之前一直脑子里有一个误解,赋值语句的返回值应该是1(成功赋值)或0(赋值失败) 今天其实在学linux的时候突然揣摩了一下代码才发现这个问题: if ((dir = opendir("/home/ljz/Desktop")) == NULL) opendir返回空说明目录打开失败 这句代码里面==NULL的判断在 (dir = opendir("/home/ljz/Desktop")) 这个赋值语句之外判断,这说明了 赋值语句的返回值就是变量所赋的值 所以才能这么写 基础不牢地动山摇呀QAQ 阅读详情

相关推荐

linux opendir,linux opendirreaddir的使用

1 opendir#include #include DIR *opendir(const char *name);传入name路径,成功则返回非空DIR指针,否则返回NULL2 readdir#include struct dirent *readdir(DIR *dirp);int readdir_r(DIR *dirp, struct dirent *entry, struct ...

weixin_30856391的博客 783

对目录的操作(opendir

对目录的操作(opendir), 详细介绍了目录的具体功能参数返回值,以及各种举例说明。

a2998658795的博客 6600

apue读书笔记【八】:目录操作opendir readdir closedir

头文件: #include #include opendir(): 函数原型: DIR * opendir(const char* path); 打开一个目录,在失败的时候返回NULL(如果path对应的是文件,则返回NULL) DIR 结构体的原型为:struct_dirstream        在linux系统中:         typedef struct __di

a172742451的专栏 726

Linux 目录访问(opendir/closedir/readdir

/ 存储获取的目录内容。//储存获取的目录流,给readdir作为参数。通常我们是不需要两个隐藏文件夹的,因此在遍历的时候直接跳过了。,.表示当前文件夹, ..表示当前文件夹的父文件夹。是在Unix 以及所有类unix系统中,注:需要注意的一个点是,

weixin_74056357的博客 1301

文件操作opendir()/readdir()/closedir()/stat() .

头文件: #include #include 在Linux下opendir()readdir()closedir()这三个函数主要用来遍历目录。 int stat(const char *restrict pathname, struct stat *restrict buf); 提供文件名字,获取文件对应属性。 opendir(): 函数原型: DIR * ope

boyemachao的专栏 1706

Linux 文件操作函数 opendir()readdir()closedir()stat()

头文件: #include #include 在Linux下opendir()readdir()closedir()这三个函数主要用来遍历目录。 int stat(const char *restrict pathname, struct stat *restrict buf); 提供文件名字,获取文件对应属性。 opendir(): 函数原型: DIR *

Luohan_CSDN的专栏 1544

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

转载自CSDN博主: 奔跑的路 基于目前学习Csapp,感觉讲的不错,所以转发! 注:为什么要说目录文件?其实在linux中目录也是一种文件,只是它的内容是上级的目录和当前目录下的文件信息等,详情可以看看相关深入的书籍 opendir(打开目录) 相关函数open,readdirclosedir,rewinddir,seekdir,telldir,scandir 表头文件#include&l...

计算机科学与技术专业学生的成长之路 1169

linux opendir路径_linux opendir readdir closedir函数

在Linux下opendir()readdir()closedir()这三个函数主要用来遍历目录。在使用这三个函数前必须先包括以下两个头文件:#include #include opendir函数的原型为:DIR *opendir(const char *name);它返回一个DIR*类型,这就是一个句柄啦,你不用管它的内部结构是什么样的,只要知道这个句柄就是等一下要传给readdir()函数...

weixin_32254267的博客 381

目录文件相关函数(opendirreaddirclosedir、chmod/fchmod、stat/lstat/fstat)

opendir函数用来打开一个目录文件: #include <dirent.h> DIR *opendir(const char *name); Ø DIR是用来描述一个打开的目录文件的结构体类型 Ø 成功时返回目录流指针;出错时返回NULL readdir函数用来读取目录流中的内容: #include <dirent.h> struct dirent *readdir(DIR *dirp); Ø struct dirent是用来描述目录流中一个目录项的结构体类型 Ø 包含

邵潇涵 592

opendirreaddir, closedir, stat函数的使用

判断模式,有两种方法:(1)mode与单个种类相&,不为0即为真 (2)mode与全1(即7)相&,判断是否等于想要的模式。对应00007 (用最后三位来代表others)判断wrx模式,单个相&,判断是否为0(法一)要准备一个放文件属性的结构体,并取其地址传入。法二:与全1相&,判断是否相等。文件编号(索引号):ino。ls功能,实现目录名显示。

weixin_64031674的博客 186

linux opendir路径_linux 目录操作函数opendir readdir closedir,文件stat

#include #include DIR *opendir(const char *p a t h n a m e ) ;返回:若成功则为指针,若出错则为N U L Lstruct dirent *readdir(DIR *d p ) ;返回:若成功则为指针,若在目录尾或出错则为N ULLint closedir(DIR *d p ) ;返回:若成功则为0,若出错则为-1D I R结构是一个内部...

weixin_36081485的博客 552

c语言 递归遍历目录(statopendirreaddirclosedir

文章目录1、 使用函数介绍2、代码实现 1、 使用函数介绍 int lstat(cosnt char* path,struct stat* buf); 参数: path 名字 buf 查询到的文件属性 返回值: 成功 0 失败 -1 DIR* opendir(cosnt char* name); 参数: name 目录名 返回值: 成功:返回指向目录结构体指针, 失败:NULL int closedir(DIR* dirp); 参数: d

weixin_45715405的博客 2278

遍历、解析与释放:目录操作三剑客[ opendir(), readdir(), closedir() ]

本文深入解析C语言中目录操作的三个核心函数opendir()readdir()closedir(),详细介绍了如何高效遍历和解析目录内容。通过实际代码示例和性能优化技巧,帮助开发者掌握目录操作的最佳实践,包括错误处理、资源管理和跨平台兼容性等关键知识点。

weixin_30328063的博客 873

opendir\readdir

lseek功能:修改文件的读写指针位置,仅移动指针,不会读写数据,也不会改变文件大小fdoffsetoff_twhenceSEEK_SETSEEK_CURSEEK_ENDoffset:正数向后移;负数向迁移;

2601_96587451的博客 164

linux 文件及目录操作 chmod,getcwd,chdir,mkdir,rmdir,opendirreaddir,seekdir,telldir、closedirstat、fstat

改变目录或文件的访问权限: #include <sys/stat.h> int chmod(const char* path, mode_t mode); //path 参数指定的文件被修改为具有 mode 参数给出的访问权限 获取、改变当前目录: #include <unistd.h> //头文件 char *getcwd(char *buf, size_t...

CLZHIT的博客 910

Linux高并发服务器开发 第十三天(文件系统概念 stat/lstat truncate link/unlink 目录操作函数(opendir/closedir/readdir))

硬链接计数为0 (没有 dentry对应) 的文件仍不会马上被释放。要等到所有打开该文件的进程运行结束,没有任何进程使用该文件,此时,系统择机释放该文件。- 一组规则,规定对文件的存储及读取的方式、方法。-vi具有穿透性,读取的是mk.soft指向的文件内容,而readlink读取的是mk.soft本身的内容。- 程序运行结束,打开的文件、申请的内存空间,会被系统自动释放。- 大多数的inode保存在磁盘中,少量常用、进期使用的inode保存内存中。- 调用unlink,只是让文件具备了被释放的条件。

m0_53349772的博客 976

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

From:http://blog.chinaunix.net/uid-27213819-id-3810699.html注:为什么要说目录文件?其实在linux中目录也是一种文件,只是它的内容是上级的目录和当前目录下的文件信息等,详情可以看看相关深入的书籍opendir(打开目录)相关函数open,readdirclosedir,rewinddir,seekdir,telldir,scandir表...

weixin_39548541的博客 383
上一篇: 用Linux命令查看已安装的软件版本
下一篇: linux C 遍历目录及其子目录 opendir -> readdir -> closedir
angle_birds
博客等级 码龄15年 161粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值