6S081-find

find

image.png

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

void find(char* path, const char* target) {
    int fd;
    struct dirent dt;
    struct stat st;
    char buf[256];
    char* p;

    //无法打开文件
    if ((fd = open(path, 0)) < 0) {
        fprintf(2, "can't open path like %s\n", path);
        return;
    }
    //读不到fd的stat
    if (fstat(fd, &st) < 0) {
        fprintf(2, "can't stat pathfire %s\n", path);
        close(fd);
        return;
    }

    //path不是目录
    if (st.type != T_DIR) {
        fprintf(2, "it's not a DIR: %s", path);
        close(fd);
        return;
    }

    if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {
        printf("find: path too long\n");
    }

    strcpy(buf, path);
    p = buf + strlen(buf); // p 指向buf的末尾\0处
    *p++ = '/';   // 在p处添加/,并且p后移一位

    // 循环读目录项结构体
    while(read(fd, &dt, sizeof(dt)) == sizeof(dt)) {
        if (dt.inum == 0) continue;
        memmove(p, dt.name, DIRSIZ); // 将dt.name指向内存中的位置DIRSIZ个粘贴到p处
        p[DIRSIZ] = 0;//DIRSIZ是目录项名字的最大长度,一般为14
        // 这里意思标记字符串结束标记

        if (stat(buf, &st) < 0) {// 目录项读不到
            printf("find: cannot stat %s\n", buf);
            continue;
        }
        if (st.type == T_DIR && strcmp(".", p) != 0 && strcmp("..", p) != 0) {
            find(buf, name);
        }
        else if(strcmp(name, p)==0){
            printf("%s\n", buf);
        }
    }
    close(fd);
}

int main(int argc, char* argv[]) {

    if (argc != 3) {
        printf("pls input like find [path] [filename]\n");
        exit(1);
    }
    find(argv[1], argv[2]);
    exit(0);
}
~

在这里插入图片描述

思路

  1. 模仿ls.c,遍历path的目录项,读到dir递归,读到file就判断是否跟name一样

不会的

  1. ls.c里面有几个系统调用查了资料才会,memmove(p, dt.name, DIRSIZ)memmove 函数将 dt.name指向的内存区域中的 DIRSIZ个字节的数据复制到 p 指向的内存区域中。这里DIRSIZ是宏定义,表示目录项的最大长度,一般是14
  2. 后半段p的位置需要注意,ls.c中先把path复制到buf中,然后在buf的末尾加了个/,再把p指向/后一个位置,后面的dt.name在p处往后添,但是p一直都在dt.name的首位。所以才可以用p跟name进行比较。
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值