当前位置: 首页 > news >正文

文件IO——目录操作

目录

  • 前言
  • 一、基本概念
  • 二、创建目录
  • 三、删除目录
  • 四、打开目录
  • 五、进入目录
  • 六、读取目录
  • 七、练习
    • 1.
      • 代码实现
    • 2.
      • 1.代码实现
      • 2.代码实现

前言

之前设计的程序只能访问某个路径下的某个文件,如果打算一次访问某个路径下的多个不同类型的文件,就需要用户手动调用open函数实现,但是当文件数量较多时,这种方案并不能满足需求,那请问是否有比较轻松高效的方式来实现访问某个路径下的多个不同类型的文件呢?当然是有的,在Linux系统下一切皆文件,目录在Linux系统下也属于文件类型之一,可以通过系统IO来进行访问,常见的访问目录的接口有:opendir、readdir、chdir、mkdir、rmdir、remove、getcwd、rewindir等。

在这里插入图片描述

一、基本概念

在Linux系统下目录是一种特殊的文件,只不过目录存储的数据的最小单位并不是字符,而是目录项,所以目录与普通文件又有所区别,另外,Linux文件系统下目录和文件夹的含义也并不相同,目录的本质是索引,文件夹的本质是容器。

也就是说,目录是用来保存项目的索引,而不用保存项目本身。Linux 和 UNIX 中的目录并不保存它里面的文件。它们只是记录文件位置的信息。

举个例子:目录和文件夹的区别就相当于门牌号和房子的区别,房子里面可以住人或者存放物品,而门牌号只是记录房子所在的位置,方便用户寻找和访问。

在这里插入图片描述
可以看到,在 Linux 或 Unix 操作系统中所有的文件和目录都被组织成以一个根节点开始的倒置的树状结构。

Linux系统的文件系统的最顶层是由根目录开始的,使用 / 来表示根目录。在根目录之下的既可以是目录,也可以是文件,而每一个目录中又可以包含子目录文件。如此反复就可以构成一个庞大的文件系统。

二、创建目录

Linux系统提供了一个用于创建目录的mkdir函数接口,第一个参数pathname指的是目录的路径,第二个参数mode用来指定新目录的模式。

在这里插入图片描述

三、删除目录

Linux系统提供了一个用于删除空目录的rmdir函数接口,第一个参数pathname指的是待删除目录的路径。
在这里插入图片描述

四、打开目录

Linux系统提供了一个用于打开目录的opendir函数接口,第一个参数pathname指的是待打开目录的路径。
在这里插入图片描述

五、进入目录

另外,打开目录并不意味着进入目录,而获取目录里面的文件的信息必须要先进入目录,可以用函数 chdir() 进入目录。

在这里插入图片描述

六、读取目录

Linux系统提供了一个用于读取目录的readdir函数接口,第一个参数dirp指的是待读取目录的目录指针。函数成功返回一个指向该目录中下一个目录项的指针,失败返回NULL。
在这里插入图片描述
Linux系统提供了一个用于获取文件信息的stat函数接口,第一个参数path指的是待读取文件的路径,第二个参数指的是获取的文件信息结构体的地址。
在这里插入图片描述

七、练习

1.

设计程序,利用操作目录的函数接口实现读取某个路径下的目录并把该目录下的所有文件名称输出到终端。并且要求目录路径作为main函数参数的形式传递。

代码实现

/** Copyright (c)* * date: 2025-7-27* * author: Charles* * function name : ReadDir.c** function: 读取当前文件夹中的信息*/#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>int main(int argc, char const *argv[])
{if(argc != 2){perror("argumen is invaild!\n");exit(-1);}//打开目录DIR* dir = opendir(argv[1]);if(!dir){perror("opendir failed!\n");exit(-1);}struct dirent *dirset;//读目录下每个文件的信息while(1){dirset = readdir(dir);if(!dirset){break;}if(dirset->d_type != DT_REG || dirset->d_name[0] == '.'){continue;}printf("%ld %c [%s]\n", dirset->d_ino, dirset->d_type,dirset->d_name);}return 0;
}

2.

设计程序利用访问目录的函数接口实现获取某个目录中所有文件的名称,并利用stat函数把每个获取的文件的类型输出到终端。 提示:可以参考man手册关于stat函数的例程。

1.代码实现

/** Copyright (c)* * date: 2025-7-27* * author: Charles* * function name : ReadDir.c** function: 读取当前目录每个文件的信息*/#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>const char* get_file_type(mode_t mode){if(S_ISREG(mode)) return "普通文件";if (S_ISDIR(mode)) return "目录";if (S_ISCHR(mode)) return "字符设备";if (S_ISBLK(mode)) return "块设备";if (S_ISFIFO(mode)) return "管道(FIFO)";if (S_ISLNK(mode)) return "符号链接";if (S_ISSOCK(mode)) return "套接字";return "未知类型";
}int main(int argc, char const *argv[])
{if(argc != 2){perror("argumen is invaild!\n");exit(-1);}const char* dir_path = argv[1];printf("扫描目录: %s\n", dir_path);printf("%-30s %-15s %-15s %s\n", "文件名", "类型", "大小(字节)", "最后修改时间");printf("--------------------------------------------------------------------\n");//打开文件DIR* dir = opendir(dir_path);if(!dir){perror("opendir 失败");return -1;}//定义变量struct dirent *entry;struct stat statbuf;char file_path[1024];int cnt = 0;//读取目录信息while((entry = readdir(dir))){if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;//构建文件路径snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, entry->d_name);//调用stat函数获取信息if(0 != stat(file_path, &statbuf)){printf("获取信息失败 %s",file_path);continue;}char time[80];strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", localtime(&statbuf.st_mtime));printf("%-30s %-15s %-15ld %s\n", entry->d_name, get_file_type(statbuf.st_mode), statbuf.st_size, time);cnt++;}printf("总共扫描到 %d 个文件\n", cnt);closedir(dir);return 0;
}

2.代码实现

这个代码是手册里面的案例

#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>int   main(int argc, char *argv[]){struct stat sb;if (argc != 2) {fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);exit(EXIT_FAILURE);}if (lstat(argv[1], &sb) == -1) {perror("lstat");exit(EXIT_FAILURE);}printf("ID of containing device:  [%jx,%jx]\n",(uintmax_t) major(sb.st_dev),(uintmax_t) minor(sb.st_dev));printf("File type:                ");switch (sb.st_mode & S_IFMT) {case S_IFBLK:  printf("block device\n");            break;case S_IFCHR:  printf("character device\n");        break;case S_IFDIR:  printf("directory\n");               break;case S_IFIFO:  printf("FIFO/pipe\n");               break;case S_IFLNK:  printf("symlink\n");                 break;case S_IFREG:  printf("regular file\n");            break;case S_IFSOCK: printf("socket\n");                  break;default:       printf("unknown?\n");                break;}printf("I-node number:            %ju\n", (uintmax_t) sb.st_ino);printf("Mode:                     %jo (octal)\n",(uintmax_t) sb.st_mode);printf("Link count:               %ju\n", (uintmax_t) sb.st_nlink);printf("Ownership:                UID=%ju   GID=%ju\n",(uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid);printf("Preferred I/O block size: %jd bytes\n",(intmax_t) sb.st_blksize);printf("File size:                %jd bytes\n",(intmax_t) sb.st_size);printf("Blocks allocated:         %jd\n",(intmax_t) sb.st_blocks);printf("Last status change:       %s", ctime(&sb.st_ctime));printf("Last file access:         %s", ctime(&sb.st_atime));printf("Last file modification:   %s", ctime(&sb.st_mtime));exit(EXIT_SUCCESS);}

在这里插入图片描述

希望各位靓仔靓女点赞,收藏,关注多多支持,我们共同进步,后续我会更新更多的面试真题,你们的支持将是我前进最大的动力。

在这里插入图片描述

http://www.dtcms.com/a/301753.html

相关文章:

  • 大模型蒸馏理论概述
  • 【分布式存储】聊聊一致性哈希算法原理和实现
  • Linux图片元数据提取完全指南:从基础到高级的完整教程
  • day25
  • EPOLLONESHOT 深度解析:Linux epoll 的单次触发机制
  • 单表查询-or优化
  • SpringIoCDI
  • Java 集合进阶:从 Collection 接口到迭代器的实战指南
  • AI入门学习-模型评估示例讲解
  • 解决浏览器无法删除cookie的问题
  • JavaSE知识点(2)
  • mybatis的insert(pojo),会返回pojo吗
  • 2507C++,APC可以干的活
  • Leetcode 3628. Maximum Number of Subsequences After One Inserting
  • mybatis-plus逻辑删除配置
  • 高可用集群KEEPALIVED实战解析
  • Gradio全解8——ChatInterfaceChatbot:聊天界面类与聊天机器人(2)——ChatInterface的自定义函数和界面
  • 芯片库和标准库寻找的方法
  • print(“\033[31m红\033[32m绿\033[34m蓝\033[0m默认色“)
  • 随机密码生成
  • Spring IOC 容器 **默认注册 Bean** 的 8 条规则
  • 网络服务综合项目
  • 数据结构基础内容(第七篇:堆、哈夫曼树)
  • SABR-Net
  • Linux 系统文件夹结构及用途说明
  • 《频率之光:共振之战》
  • 题解:CF1010C Border
  • Python异常处理:金融风控系统中的救命盾牌
  • Web开发系列-第13章 Vue3 + ElementPlus
  • 第十二讲:C++继承