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

MIB 6.1810实验Xv6 and Unix utilities(5)find

难度:moderate

Write a simple version of the UNIX find program for xv6: find all the files in a directory tree with a specific name. Your solution should be in the file user/find.c.

题目要求:实现find ,即在某个路径中,找出某个文件

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/fcntl.h"char* fmt_name(char *path){static char buf[DIRSIZ+1];char *p;//find first character after last slashfor(p=path+strlen(path);p>=path&&*p!='/';p--);p++;memmove(buf,p,strlen(p)+1);return buf;
}void eq_print(char *fileName,char *findName){if(strcmp(fmt_name(fileName),findName)==0){printf("%s\n",fileName);}
}
void find(char *path,char *findName){char buf[512], *p;int fd;struct dirent de;struct stat st;if((fd = open(path, O_RDONLY)) < 0){fprintf(2, "ls: cannot open %s\n", path);return;}if(fstat(fd, &st) < 0){fprintf(2, "ls: cannot stat %s\n", path);close(fd);return;}/*int fd;声明一个文件描述符变量 fd,用于在程序中表示打开的文件或目录。struct dirent de;定义了一个结构体 dirent 变量 de,通常用于存储读取目录时的目录项信息。struct stat st;:定义了一个结构体 stat 变量 st,用于存储文件或目录的状态信息。if((fd = open(path, O_RDONLY)) < 0){ ... }:尝试以只读模式打开指定路径的文件或目录。如果 open() 函数返回的文件描述符小于 0(表示打开失败),则输出错误信息,并返回。if(fstat(fd, &st) < 0){ ... }:如果文件或目录成功打开,则使用 fstat() 函数获取文件描述符 fd 对应文件或目录的状态信息,并将结果存储在 st 结构体中。如果获取状态信息失败(fstat() 返回值小于 0),则输出错误信息,并关闭文件描述符后返回。  */switch(st.type){case T_DEVICE:case T_FILE:eq_print(path,findName);break;case T_DIR:if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){printf("find: path too long\n");break;}strcpy(buf, path);p = buf+strlen(buf);*p++ = '/';while(read(fd, &de, sizeof(de)) == sizeof(de)){if(de.inum ==0||de.inum==1||strcmp(de.name,".")==0 || strcmp(de.name,"..")==0)continue;memmove(p, de.name, strlen(de.name));p[strlen(de.name)] = 0;find(buf,findName);}break;
/*循环:遍历目录项 read(fd, &de, sizeof(de)):使用read函数从文件描述符 fd中读取一个目录项的内容,并将读取的内容存储在 de 变量中。只要 read 函数成功读取一个目录项的大小(sizeof(de)),就会继续执行循环。循环内部:首先,通过检查 de.inum(目录项的inode号码)是否等于0或1,以及检查目录项的名称是否是.或..,来过滤掉特殊的目录项。.(点)表示当前目录,..(点点)表示父目录,它们在此处被跳过,不做进一步处理。如果目录项既不是特殊目录项.(点)或 ..(点点),也不是 inode 号码为 0 或 1,则会执行以下操作:memmove(p, de.name, strlen(de.name));:将目录项的文件名 de.name 复制到一个指定的缓冲区 buf 中,从指针 p 指向的位置开始存储。这里使用 memmove 函数是为了确保将文件名正确复制到指定的位置。p[strlen(de.name)] = 0;:在复制文件名后,将字符串末尾添加一个空字符 \0,以确保字符串以空字符结尾,形成一个 C 风格的字符串。最后,调用 find(buf, findName);,以递归方式在当前路径下的子目录中继续查找名为 findName 的文件或目录。在当前目录下的每个子目录中进行深度优先的查找操作。
*/}close(fd); 
}
/*
void find(char *path, char *findName):递归函数,接收两个参数,path 表示要搜索的路径,findName 表示要查找的文件或目录名。
代码开始通过 open() 函数尝试打开指定的路径,如果失败则会输出错误信息并返回。
使用 fstat() 函数获取文件的状态信息,如果失败也会输出相应的错误信息并关闭文件描述符后返回。
接下来 定义了一个缓冲区buf和指针p,用于构建要查找的文件或目录的完整路径。
使用 switch 语句检查文件类型:
T_FILE:表示当前路径是一个文件,则调用 eq_print() 函数
T_DIR:表示当前路径是一个目录,则进行目录的遍历和递归查找。首先检查路径长度是否过长,如果是,则输出相应错误信息。然后将当前路径复制到 buf 中,并在其末尾添加 /。接着使用 read() 函数读取目录项,并在循环中遍历目录下的所有文件和子目录。在目录遍历的循环中,会检查每个目录项的 inum 值是否为0或1(通常表示未使用的或损坏的inode),以及是否是.或..目录(表示当前目录和父目录).如果是则跳过不处理。
将当前目录项的名字添加到 buf 中,并递归调用 find() 函数,以此在当前目录中查找与 findName 匹配的文件或目录。
最后关闭打开的文件描述符 fd。
*/int main(int argc, char *argv[])
{if(argc>3){printf("find: find <path> <fileName>\n");exit(0);}find(argv[1],argv[2]);exit(0);
}

fmtname函数示意图 

find函数示意图:

 

实验结果:

http://www.lryc.cn/news/237813.html

相关文章:

  • 百度爬虫的工作原理解析
  • Linux入门必备指令
  • linux系统环境下mysql安装和基本命令学习
  • Monitor 原理
  • Java核心知识点整理大全7-笔记
  • Flink Operator 使用指南 之 全局配置
  • 手把手教你通过CODESYS V3进行PLC编程(一)
  • 《算法通关村—进制转换问题处理模板》
  • python接口自动化测试之接口数据依赖
  • s28.CentOS、Ubuntu、Rocky Linux系统初始化脚本v6版本
  • go同步锁 sync mutex
  • 使用项目自动生成的dokcerfile第一次构建时把加载aps5.0失败无法找到加载的文件
  • ACREL DC energy meter Application in Indonesia
  • 报错!Jupyter notebook 500 : Internal Server Error
  • 2023.11.21使用<button>元素来触发form表单和数据提交
  • leetcode:504. 七进制数
  • centos安装指定版本docker
  • PPT幻灯片里的图片,批量提取
  • 《Fine-Grained Image Analysis with Deep Learning: A Survey》阅读笔记
  • 【网络安全】伪装IP网络攻击的识别方法
  • redis非关系型数据库
  • LeetCode 0053. 最大子数组和:DP 或 递归(线段树入门题?)
  • 二十三种设计模式全面解析-解密职责链模式:请求处理的设计艺术
  • 【linux】安装telnet
  • 深入探索 PaddlePaddle 中的计算图
  • 西南科技大学814考研一
  • 【网络编程】简述TCP通信程序,三次握手,四次挥手
  • 【ARM Trace32(劳特巴赫) 使用介绍 5 -- Trace32 ELF 文件加载介绍】
  • Linux(4):Linux文件与目录管理
  • Altium Designer学习笔记2