1.概念引入
目录IO的作用(开发的应用场景):实现目录检索find,显示目录中的目录项显示ls
目录IO基本的函数:
opendir:打开一个目录
closedir:关闭一个目录
readdir:读取一个目录里面的一个目录项(获取目录中的目录项信息--就是说这个文件夹里面有什么东西)
目录:文件 目录 目录项
钱包:钱 银行卡 身份证... 钱包项
2.opendir:打开一个目录
#include <dirent.h>
DIR *opendir(const char *name); FILE * 类似,都是指向结构体的指针,结构体多是存放对应对象的元信息
返回值:RETURN VALUE
The opendir() functions return a pointer to the directory stream(数据流:字节流). (打开的目录里面的)目录信息当成数据字节流来传输
On error, NULL is returned, and errno is set appropriately.
成功:返回一个目录流指针,这个流指针同理也会指向一个结构体,该结构体存放的信息用于对应该目录项的操作(读取 关闭)。
失败:NULL
形参1:
设置你要打开的目录的路径
目录项 = 文件 + 文件夹
3.closedir:关闭一个目录
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
形参1:opendir打开目录成功的返回值(目录流指针)
返回值: The closedir() function returns 0 on success. On error, -1 is returned,
关闭成功:
0
关闭失败:
-1
4.readdir:读取一个目录
#include <dirent.h>
struct dirent * readdir(DIR *dirp);
返回值: On success, readdir() returns a pointer to a dirent structure.(指向目录项的结构体。该结构体里面存放的就是我们需要获取的信息)
返回下一个目录项的结构体的首地址,这个结构体就存放了对应的目录项的信息(目录项的名字和大小等信息).
If the end of the directory stream is reached, NULL is returned and errno is not changed. If an error occurs, NULL is returned
读取成功:返回下一个目录项的结构体指针,这个结构体指针就是存放下一个目录项的信息。
读取失败:NULL
读到目录流末尾:NULL
形参1:opendir打开目录成功的返回值(目录流指针)
struct dirent {
ino_t d_ino; /* Inode number --- 目录项的索引号*/
off_t d_off; /* Not an offset; see below */ 目录项在该目录里面的偏移量
unsigned short d_reclen; /* Length of this record */ 目录项的实际大小 -- 受名字的长度影响
unsigned char d_type; /* Type of file; not supported 目录项的类型(主要的信息)
by all filesystem types */
char d_name[256]; /* Null-terminated filename */ 目录项的名字(主要的信息)
};
1).关于readdir:
2).目录项类型分类:
5.目录检索的实现
/******************************************************************************************************
* @file name: : 目录检索.c
* @brief :检索所提供的文件名是否存在
* @author :wvjnuhhail@126.com
* @date :2024/07/11
* @version 1.0 :V1.0
* @property :暂无
* @note :None
* CopyRight (c) 2023-2024 wvjnuhhail@126.com All Right Reseverd
*******************************************************************************************************/
/*
实现思路:
了解读取目录项的顺序
读取目录的特点:不管什么时候,遇到目录就需要立刻打开这个目录进去读取里面的目录项
int Fun(目录的路径)
{
opendir()
while(1)
{
readdir();
如果是读到文件夹
Fun(新的文件夹的路径)
如果是文件呢?
strcmp
}
}
*/
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#define PATH_MAN_LEN 256 * 50
/*******************************************************************************************************
* @funname : SearchFile
* @brief : 拷贝文件
* @param :
* @a:obj_dir
* @b:obj_file
* @retval : int
* @date :2024/07/11
* @version :V1.0
* @note :None
*******************************************************************************************************/
// 传入检索的目录,需要检索的文件
int SearchFile(const char *obj_dir, const char *obj_file)
{
// 打开目录
DIR *dp = opendir(obj_dir);
if (NULL == dp)
{
perror("opendir...");
exit(1);
}
// 定义一个结构体指针
struct dirent *eq;
char complete_path[PATH_MAN_LEN];
while (1)
{
memset(complete_path, 0, PATH_MAN_LEN);
eq = readdir(dp);
if (eq == NULL)
{
break;
}
// 检索第一个元素下标是0,成员是 "."
if (eq->d_name[0] == '.')
{
continue;
}
if (obj_dir[strlen(obj_dir) - 1] == '/')
{
// 有输入'/',不需要补全
sprintf(complete_path, "%s%s", obj_dir, eq->d_name);
}
else
{
// 终端没有输入'/',补全
sprintf(complete_path, "%s/%s", obj_dir, eq->d_name);
}
// 判断如果是目录,递归检索
if (eq->d_type == DT_DIR)
{
// 拼接后的路径保存在数组complete_path中
SearchFile(complete_path, obj_file);
}
// 如果是文件
if (eq->d_type == DT_REG)
{
// 与所给的名字进行匹配
if (strcmp(eq->d_name, obj_file) == 0)
{
printf("Hit Obj ----%s\n", complete_path);
}
}
else
{
// 假如查找的文件不存在,提示未找到
printf("Not Find\n");
break;
}
}
closedir(dp);
return 0;
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("参数有误,需要3个参数!\n");
return -1;
}
if (SearchFile(argv[1], argv[2]) == -1)
{
printf("目录检索失败!\n");
return -1;
}
return 0;
}