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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)