0
点赞
收藏
分享

微信扫一扫

目录操作和虚拟文件系统

40dba2f2a596 2022-02-05 阅读 36

1.stat

假设一个路径是/opt/file,则查找的顺序是:

①读出inode表中第2项(根目录inode),从中找出根目录数据块位置

②从根目录数据块找出文件名为opt的记录,从记录中独处inode号

③读出opt目录的inode,从中找出它的数据块位置

④从opt目录的数据块中找出文件名为file的记录,从记录中读出inode号

⑤读出file文件的inode

2.opendir(3)/readdir(3)/closedir(3)

用于遍历目录数据块中的记录。

opendir:打开一个目录,返回一个Dir *指针代表这个目录,类似FILE *指针的句柄。

closedir:关闭这个句柄,把Dir *指针传给readdir读取目录数据块中的记录,每次返回一个指向struct dirent的指针,反复读可以遍历所有记录,所有记录遍历完之后readdir返回NULL。

结构体struct dirent定义:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>

void printDir(char *dirname) {
    char pathname[1024];
    DIR *dir;
    struct dirent *dp;
    struct stat st;
    if (!(dir=opendir(dirname))) {
        perror("opendir");
        exit(1);
    }
    while (dp = readdir(dir))
    {
        if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) {
            continue;
        }
        sprintf(pathname, "%s/%s", dirname, dp->d_name);
        if (stat(pathname, &st) < 0) {
            perror("stat");
            exit(1);
        }
        if (S_ISDIR(st.st_mode)) {
            printDir(pathname);
        }
        printf("%s\t", dp->d_name);
    }
    putchar(10);
    closedir(dir);
}

int main(int argc, char **argv) {
    if (argc < 2) {
        printf("usage:cmd + path");
        return 1;
    }

    printDir(argv[1]);
    return 0;
}

3.VFS

Virtual Filesystem

Linux支持各种各样文件系统格式,然后这些文件系统都可以mount到某个目录下,使我们看到一个统一目录树,各种文件系统上的目录和文件用ls命令看是一样的,读写操作是一样的,这是如何做到的?

Linux内核在各种不同的文件系统格式之上做了一个抽象层,使文件,目录,读写访问等概念称为抽象层概念,因此各种系统看起来用起来都一样,这个抽象层为虚拟文件系统。

4.dup和dup2

都可用来赋值一个现存的文件描述符,使两个文件描述符指向同一个file结构体。

如果两个文件描述符指向同一个file结构体,File,Status,Flag和读写位置只保存一份在file结构体,并且file结构体的引用计数是2.

如果2次open同一文件得到两个文件描述符,则每个描述符对应一个不同的file结构体,可以有不同的File,Status,Flag和读写位置。

区分这两种情况:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main(void) {
    int fd, save_fd;

    if ((fd = open("test.txt", O_RDWR)) < 0) {
        perror("open");
        exit(1);
    }
    save_fd = dup(1);
    dup2(fd, 1);
    close(fd);
    write(1, "123456789", 9);
    dup2(save_fd, 1);
    write(1, "123456789", 9);
    close(save_fd);
    return 0;
}
举报

相关推荐

0 条评论