找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 1623|回复: 0

linux C 遍历目录及其子目录 opendir -> readdir -> closedir

[复制链接]

96

主题

6

回帖

108

积分

屌炸天

积分
108
发表于 2018-5-30 14:50:44 | 显示全部楼层 |阅读模式
1 在linux下遍历某一目录下内容LINUX下历遍目录的方法一般是这样的
2 打开目录->读取->关闭目录
3 相关函数是opendir -> readdir -> closedir,其原型如下:
4 #include <dirent.h>
5 DIR *opendir(const char *dirname);
6 struct dirent *readdir(DIR *dirp);
7 int closedir(DIR *dirp);
1 dirent结构体定义:
2 On Linux, the dirent structure is defined as follows: struct dirent {    ino_t          d_ino;       /* inode number */   
                                                                  off_t          d_off;       /* offset to the next dirent */   
                                                                  unsigned short d_reclen;    /* length of this record */   
                                                                  unsigned char d_type;      /* type of file */   
                                                                  char           d_name[256]; /* filename */
                                                              };
3
4 其中inode表示存放的是该文件的结点数目(具体可了解linux下的文件系统),d_off 是文件在目录中的编移,这两个基本很少用。
5
6 d_type表示档案类型:
7
8
9 enum
10 {
11     DT_UNKNOWN = 0,
12     #define DT_UNKNOWN DT_UNKNOWN
13     DT_FIFO = 1,
14     #define DT_FIFO DT_FIFO
15     DT_CHR = 2,
16     #define DT_CHR DT_CHR
17     DT_DIR = 4,
18     #define DT_DIR DT_DIR
19     DT_BLK = 6,
20     #define DT_BLK DT_BLK
21     DT_REG = 8,
22     #define DT_REG DT_REG
23     DT_LNK = 10,
24     #define DT_LNK DT_LNK
25     DT_SOCK = 12,
26     #define DT_SOCK DT_SOCK
27     DT_WHT = 14
28            #define DT_WHT DT_WHT
29 };
30
31 d_reclen认为是纪录的长度,计算方式应该是4(d_ino)+4(d_off)+2(d_reclen)+1(d_type)+1(补齐位)+4N(d_name会自动补齐:
           1.jpg为8,12.jpg也为8,1234.jpg也为8,12345.jpg则为12);所以一般d_reclen是20和24(其中.和..是16)。
32
33 d_name表示文件名,如test.jpg
34
35  
36
37 unsigned char d_type,文件或目录的类型。它有可能的取值如下:
38                    DT_UNKNOWN,未知的类型
39                    DT_REG,普通文件
40                    DT_DIR,普通目录
41                    DT_FIFO,命名管道或FIFO
42                    DT_SOCK,本地套接口
43                    DT_CHR,字符设备文件
44                    DT_BLK,块设备文件





linux C 遍历目录及其子目录 举例:

[C] 纯文本查看 复制代码
#include <stdio.h>  
#include <string.h> 
#include <stdlib.h>  
#include <dirent.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <sys/types.h> 
#include <iostream>


using namespace std;
void listDir(char *path)  //main函数的argv[1] char * 作为 所需要遍历的路径 传参数给listDir   
{  
        DIR              *pDir ;  //定义一个DIR类的指针
        struct dirent    *ent  ;   //定义一个结构体 dirent的指针,dirent结构体见上
        int               i=0  ;  
        char              childpath[512];  //定义一个字符数组,用来存放读取的路径
  
        pDir=opendir(path); //  opendir方法打开path目录,并将地址付给pDir指针
        memset(childpath,0,sizeof(childpath)); //将字符数组childpath的数组元素全部置零 
  
  
        while((ent=readdir(pDir))!=NULL) //读取pDir打开的目录,并赋值给ent, 同时判断是否目录为空,不为空则执行循环体  
        {  
  
                if(ent->d_type & DT_DIR)  //读取 打开目录的文件类型 并与 DT_DIR进行位与运算操作,即如果读取的d_type类型为DT_DIR (=4 表示读取的为目录)
                {  
  
                        if(strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)  
                                    //如果读取的d_name为 . 或者.. 表示读取的是当前目录符和上一目录符, 用contiue跳过,不进行下面的输出  
                                continue;  
  
                        sprintf(childpath,"%s/%s",path,ent->d_name);  //如果非. ..则将 路径 和 文件名d_name 付给childpath, 并在下一行prinf输出
                        printf("path:%s\n",childpath);  
  
                        listDir(childpath);  //递归读取下层的字目录内容, 因为是递归,所以从外往里逐次输出所有目录(路径+目录名),
                                         //然后才在else中由内往外逐次输出所有文件名
  
                }  
              else  //如果读取的d_type类型不是 DT_DIR, 即读取的不是目录,而是文件,则直接输出 d_name, 即输出文件名
              {
                  cout<<ent->d_name<<endl;  //cout<<childpath<<"/"<<ent->d_name<<endl;  输出文件名 带上了目录 
              }
        }  
  
}  
  
int main(int argc,char *argv[])  
{  
        listDir(argv[1]); //第一个参数为 想要遍历的 linux 目录 例如,当前目录为 ./ ,上一层目录为../  
        return 0;  
}





1 运行结果
2 ./a.out ./
3 path:.//test
4 path://test/test
5 abcde.cc
6 mysql.cc
7 a.out
8 direc.cc~
9 direc.cc










您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Comsenz Inc. ( 粤ICP备15088888号-2 )

GMT+8, 2024-4-20 22:04 , Processed in 0.119940 second(s), 10 queries , File On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表