linux 目录遍历函数 opendir readdir closedir dup dup2 fcntl

目录遍历 opendir  readdir  closedir 

复制代码
 1 /*
 2     man 3(标准C库函数)
 3     man 3 opendir       man 3 readdir       man 3 closedir
 4     #include <sys/types.h>
 5     #include <dirent.h>
 6     DIR* opendir(const char* name);
 7         作用:打开一个目录
 8         参数:
 9             - name:需要打开的目录的名称
10         返回值:
11             DIR* 类型,  理解为目录流
12             错误返回:NULL
13     #include <dirent.h>
14     struct dirent* readdir(DIR* dirp);
15         作用:读取目录中的数据
16         参数:
17             dirp是opendir返回的结果
18         返回值:
19             struct dirent:代表读取到的文件的信息  
20             读取到了末尾或者失败了,返回NULL
21 
22     #include <sys/types.h>
23     #include <dirent.h>
24     int closedir(DIR* dirp);
25         作用:关闭目录
26 */
27 #define _DEFAULT_SOURCE     //DT_DIR
28 #include <sys/types.h>
29 #include <dirent.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>         //exit(0):可以退出进程  return只能结束当前函数
33 int getFileNum(const char* path);//函数声明
34 //读取某个目录下所有的普通文件的个数
35 int main(int argc, char* argv[])
36 {
37     if(argc < 2)
38     {
39         printf("%s path\n",argv[0]);
40         return -1;
41     }
42     int num = getFileNum(argv[1]);
43     printf("普通文件的个数: %d\n",num);
44     return 0;
45 }
46 //用于获取目录下所有普通文件的个数
47 int getFileNum(const char* path)
48 {
49     //1.打开目录
50    DIR* dir = opendir(path);
51    if(dir == NULL)
52    {
53     perror("opendir");
54     exit(0);
55    }
56     //记录普通文件个数
57    int total = 0;
58    struct dirent* ptr;
59    while((ptr = readdir(dir)) != NULL)
60    {
61         //获取名称
62         char* dname = ptr->d_name;//文件名  
63         //忽略掉 . 和 ..
64         if(strcmp(dname,".") == 0 || strcmp(dname,"..") == 0)//strcmp  等于返回0 小于返回负数 大于返回正数
65         {
66             continue;
67         }
68         //判断是否是普通文件还是目录
69         if(ptr->d_type == DT_DIR)
70         {
71             //目录,需要继续读取这个目录
72             char newpath[256];
73             sprintf(newpath,"%s/%s",path,dname);
74             total += getFileNum(newpath);
75         }
76         if(ptr->d_type == DT_REG)
77         {
78             //普通文件
79             total++;
80         }
81    }
82    //关闭目录
83    closedir(dir);
84    return total;
85 }
复制代码

 复制文件描述符  dup 

复制代码
 1 /*
 2     man 2 dup
 3     #include <unistd.h>
 4     int dup(int oldfd);
 5         作用:复制一个新的文件描述符
 6         fd=3,int fd1 = dup(fd),
 7         fd指向的是a.txt,  fd1也是指向a.txt
 8         从空闲的文件描述符表中找一个最小的,作为新的拷贝的文件描述符
 9         返回值:
10             成功:返回新的文件标识符
11             失败:返回-1
12 */
13 
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <string.h>
20 
21 int main()
22 {   
23     int fd = open("a.txt",O_RDWR|O_CREAT,0664);
24     int fd1 = dup(fd);
25     if(fd1 == -1)
26     {
27         perror("dup");
28         return -1;
29     }
30     printf("fd: %d\t fd1: %d\n",fd,fd1);
31     close(fd);
32     char* str = "hello,world";
33     int ret = write(fd1, str, strlen(str));
34     if(ret == -1)
35     {
36          perror("write");
37          return -1;
38     }
39     close(fd1);
40     return 0;
41 }
复制代码

                   

重定向文件描述符    dup2    

复制代码
 1 /*
 2     man 2 dup2
 3     #include <unistd.h>
 4     int dup2(int oldfd, int newfd);
 5         作用:重定向文件描述符   
 6         oldfd指向 a.txt ,  newfd 指向 b.txt
 7         调用函数成功后,newfd 和 b.txt 做close(),  newfd指向了  a.txt
 8         oldfd必须是一个有效的文件描述符
 9         返回值:dup2的返回值与newfd相同,在后续关闭文件描述符时需要关闭 newfd
10 */
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 int main()
18 {
19     int fd = open("1.txt",O_RDWR | O_CREAT,0664);//fd:3 
20     if(fd == -1)
21     {
22         perror("open");
23         return -1;
24     }
25     int fd1 = open("2.txt",O_RDWR | O_CREAT,0664);//fd1:4
26     if(fd1 == -1)
27     {
28         perror("open");
29         return -1;
30     }
31     printf("fd: %d\t  fd1: %d\n",fd,fd1);//fd:3   fd1:4
32     int fd2 = dup2(fd,fd1);
33     if(fd2  == -1)
34     {
35         perror("dup2");
36         return -1;
37     }
38     //通过fd1写数据,实际操作的是 1.txt
39     char* str = "hello,world";
40     int len = write(fd1, str, strlen(str));//此时修改fd fd1 fd2 都是指向1.txt文件
41     if(len == -1)
42     {
43         perror("write");
44         return -1;
45     }
46     printf("fd: %d\t  fd1: %d\t fd2: %d\n",fd,fd1,fd2);//fd:3 fd1:4 fd2:4
47     close(fd);
48     close(fd1);
49     return 0;
50 }
复制代码

          

 复制文件描述符   fcntl函数     设置/获取文件的状态标志  

复制代码
 1 /*
 2     man 2 fcntl
 3     #include <unistd.h>
 4     #include <fcntl.h>
 5     int fcntl(int fd, int cmd, .../可选参数/);// ...:可变参数 可写 可不写 可多写
 6         参数:
 7             - fd:表示需要操作的文件描述符
 8             - cmd:表示对文件描述符进行如何操作
 9                 - F_DUPFD: 复制文件描述符,复制的是第一个参数fd,得到一个新的文件描述符(返回值返回)
10                     int ret = fcntl(fd,F_DUPFD);
11                 - F_GETFL: 获取指定的文件描述符文件状态flag
12                     获取的flag和我们通过open函数传递的flag是一个东西
13                 - F_SETFL: 设置文件描述符文件状态flag
14                     必须项:O_RDONLY, O_WRONLY, O_RDWR 不可以被修改
15                     可选项:O_APPEND(表示文件中追加数据), O_NONBLOCK(设置成不阻塞)
16             阻塞和非阻塞:描述的是函数调用的行为
17 */
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <string.h>
22 
23 int main()
24 {
25     //1.复制文件描述符
26     //int fd = open("1.txt",O_RDONLY);
27     //int ret = fcntl(fd, F_DUPFD);
28     //2.修改或者获取文件状态flag
29     int fd = open("1.txt",O_RDWR);
30     if(fd == -1)
31     {
32         perror("open");
33         return -1;
34     }
35     //获取文件描述符的状态flag
36     int flag = fcntl(fd,F_GETFL);
37     if(flag == -1)
38     {
39         perror("fcntl");
40         return -1;
41     }
42     flag |= O_APPEND; //flag = flag | O_APPEND
43     //修改文件描述符状态的标记flag  给flag加入O_APPEND这个标记
44     int ret = fcntl(fd,F_SETFL,flag);
45     if(ret == -1)
46     {
47         perror("fcntl");
48         return -1;
49     }
50     char* str = "ZZZZZ";
51     write(fd,str,strlen(str));
52     close(fd);
53     return 0;
54 }
复制代码

           

posted on   廿陆  阅读(58)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示