文件系统与目录操作

1.mmap

mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数。

 

  • addr:如果addr参数为NULL,内核自己在进程地址空间中选择合适的地址建立映射。如果addr不是NULL,则给内核一个提示,应该从什么地址开始映射,内核会选择addr之上的某个合适的地址开始映射。建立映射后,真正的映射首地址通过返回值可得到。

  • len:需要映射的那一部分文件的长度。off参数是从文件的什么位置开始映射,必须是页大小的整数倍。

  • filedes:该文件的描述符。

  • prot:有4种取值:①PROT_EXEC:映射的这一段可执行,如映射共享库  ②PROT_READ:映射的这一段可读  ③PROT_WRITE:映射的这一段可写 ④PROT_NONE:映射的这一段不可访问。

  • flag:①MAP_SHARED:多个进程对同文件映射共享, ②MAP_PRIVATE:多个进程对同文件映射不共享 

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

int main(void) {
    int fd = open("test.txt", O_RDWR);
    if (fd < 0) {
        perror("open file");
        exit(1);
    }
    int *p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);
    ((int *)((char *)p) + 1)[0] = 0x30313233;
    munmap(p, 6);
    return 0;
}

2.虚拟文件系统VFS

【1】ext2文件系统

文件系统中存储的最小单位是Block,一个块究竟多大是格式化时确定的,

如:mke2fs的-b选项可以设定块大小是1024,2048或4096字节。

 

  • 启动块Boot Block:大小就是1KB,由PC标准确定,用来存储磁盘分区信息和启动信息,任何文件系统d都不能使用该块。

  • 超级块Super Block:描述整个分区的文件系统信息,如:块大小,文件系统版本号,上次mount的时间等。超级块在每个块组的开头都有一份拷贝 。

  • 块组描述符表GDT(Group Descriptor Table):由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,包括inode表从哪里开始,数据块从哪里开始,空闲的inode和数据块还有多少个。块组描述符表在每一个块组的开头都有一份拷贝,这些信息很重要,因此都有多份拷贝。

  • 块位图Block Bitmap:是用来描述整个块组中哪些块已用,那些块空闲,本身占一个块,其中的每个bit代表本块中一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。

  • inode位图inode bitmap:和块位图类似,本身占一个块,其中每一个bit表示一个inode是否空闲可用。

  • inode表inode table:文件类型(常规,目录,符号链接),权限,文件大小,创建/修改/访问时间等信息存在inode中,每个文件都有一个inode。

  • 数据块Data Block

        ①常规文件:文件的数据存在数据块。

        ②目录:该目录下的所有文件名和目录存在数据块。(文件名保存在所在目录的数据块中,其他信息都保存在该文件的inode中)。

        ③符号链接:如果目标路径名较短则直接保存在inode中以便更快查找,否则分配一个数据块来保存。

        ④设备文件、FIFO,socket等特殊文件:没有数据块,设备文件的主设备和次设备号保存在inode。

【2】stat(2)

读取文件的inode,然后把inode中的各种文件属性填入一个struct stat结构体传出给调用者。

stat(1)命令是基于stat函数实现的。

stat需要根据传入的文件路径找到inode。

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

int main(int argc, char *argv[]) {
    struct stat st;
    if (argc < 2) {
        printf("usage:cmd + filename,dirname\n");
        exit(1);
    }

    lstat(argv[1], &st);
    switch (st.st_mode & S_IFMT)
    {
    case S_IFREG:
        printf("Is regular file\n");
        break;
    case S_IFDIR:
        printf("Is directory\n");
        break;
    case S_IFCHR:
        printf("Is charactor device\n");
        break;
    default:
        printf("Is other file type\n");
        break;
    }
    return 0;
}

lstat: other file type

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值