win/linux遍历目录

本文介绍了如何在Windows和Linux环境下使用dirent库遍历目录,包括文件类型的说明,以及如何获取文件的详细信息。详细讲解了DIR、dirent和stat结构体的作用,并给出了操作目录和文件的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经常用到遍历目录,在win/linunx下都可以使用dirent实现。

1. windows遍历目录

【1】提供了在visual studio下使用dirent.h读取目录内文件的详细步骤,简单说来,将dirent.h的头文件包含即可;而且包含例程,如其中的ls.c

/*
 * List files and directories within a directory.
 */
static void
list_directory(
    const char *dirname)
{
    DIR *dir;
    struct dirent *ent;
                
    /* Open directory stream */
    dir = opendir (dirname);
    if (dir != NULL) {

        /* Print all files and directories within the directory */
        while ((ent = readdir (dir)) != NULL) {
            switch (ent->d_type) {
            case DT_REG:
                printf ("%s\n", ent->d_name);
                break;

            case DT_DIR:
                printf ("%s/\n", ent->d_name);
                break;

            case DT_LNK:
                printf ("%s@\n", ent->d_name);
                break;

            default:
                printf ("%s*\n", ent->d_name);
            }
        }

        closedir (dir);

    } else {
        /* Could not open directory */
        printf ("Cannot open directory %s\n", dirname);
        exit (EXIT_FAILURE);
    }
}

2. 文件类型说明

【2】介绍了如何判断文件类型

DT_UNKNOWN 未知类型

DT_REG 常规文件

DT_DIR 目录

DT_FIFO 管道

DT_SOCK socket

DT_CHR 字符设备

DT_BLK 块设备

DT_LNK 符号链接

3. 详细分析

下述内容转载自参考【3】

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

struct __dirstream   
   {   
    void *__fd;    
    char *__data;    
    int __entry_data;    
    char *__ptr;    
    int __entry_ptr;    
    size_t __allocation;    
    size_t __size;    
    __libc_lock_define (, __lock)    
   };   
typedef struct __dirstream DIR;  

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

struct dirent *readdir(DIR *dp);   
  
void rewinddir(DIR *dp);   
  
int closedir(DIR *dp);   
  
long telldir(DIR *dp);   
  
void seekdir(DIR *dp,long loc);  

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

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

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

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

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

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

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

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

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

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

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

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

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

参考资料

【1】Dirent API for Microsoft Visual Studio

【2】文件类型说明

【3】Linux下DIR,dirent,stat等结构体详解





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值