文章目录
文件
在谈文件系统前,首先谈谈什么是文件?
文件结构体
文件 = 属性 + 内容
同进程PCB,linux也有管理文件属性的结构体
-
struct file:描述文件的打开状态,每次打开文件都会创建一个 file 结构,主要记录与进程操作文件相关的信息(如文件指针位置、打开模式等)。
-
struct inode:描述文件在磁盘或文件系统中的元数据,无论文件是否被打开,inode 都存在。
-
struct stat:用于在用户空间访问文件的属性信息,系统调用通过从 inode 获取属性并填充到 struct stat 中
本文重点在前2个
文件的权限
文件权限
每个文件和目录在 Linux 中都有三类权限,分别是:
- 所有者(Owner)
- 所属组(Group)
- 其他用户(Others)
每类权限又分为三种操作权限:
- 读(r,read):允许查看文件内容或列出目录内容。
- 写(w,write):允许修改文件内容或在目录中创建、删除文件。
- 执行(x,execute):允许执行文件(如果是可执行程序)或访问目录中的文件。
这些权限被表示为一个 9 位的二进制组合,如下:
rwxrwxrwx
- 前三个字符表示文件的所有者权限。
- 中间三个字符表示文件的所属组权限。
- 最后三个字符表示其他用户的权限。
有权限则对应的二进制位为1
例如,文件权限 755 表示:rwxr-xr-x
文件掩码(umask)用于决定在创建文件或目录时默认权限会被如何设置。它是一个权限的反向屏蔽值,掩码中的位会关闭(去除)文件或目录的默认权限。
- 对于文件,默认权限为 666(即只有读和写权限,没有执行权限)。
- 对于目录,默认权限为 777(即读、写、执行权限全部开放)。
码会从这些默认权限中减去相应的权限。例如:
一个常见的掩码值为 022。这意味着从默认权限中去掉组和其他用户的写权限:
- 文件权限:666 - 022 = 644(所有者有读写权限,组和其他用户只有读权限)
- 目录权限:777 - 022 = 755(所有者有全部权限,组和其他用户有读和执行权限)
查看当前掩码:
umask
临时设置 umask(只对当前会话有效):
umask 002
永久更改 umask
将 umask 命令添加到你的 shell 启动文件中(例如 ~/.bashrc 或 ~/.profile)
文件的状态
文件有2种状态:打开和未打开
对于一个打开的文件,我们重点关注谁打开?谁进行维护?进程!因此要研究进程和文件的关系
对于一个未打开的文件,我们重点关注放在哪里?如何分门别类的放置好?因此我们需要研究linux的文件系统。
打开的文件
对于打开的文件,我们要研究进程和文件的关系。下面按照如下顺序来讲解:
- 进程如何操作文件?研究linux下的文件系统调用
- 底层是如何将进程和打开的文件联系在一起?研究struct task_struct和struct file
Linux下文件的系统调用
linux系统提供的常见文件接口:
open
write
read
close
open && close
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
#include <unistd.h>
int close(int fd);
参数介绍
pathname -- 文件路径
flags -- 文件打开方式
mode -- 文件掩码
flags参数是标志位,告诉open函数是要以读还是以写的方式打开文件。传参内容如下:
O_WRONLY:以写的方式打开文件
O_RDONLY:以读的方式打开文件
O_RDWR:以读写的方式打开文件
O_CREAT:当文件不存在时,创建文件
O_APPEND:在文件末尾追加
疑问:如何传递多个标志位?
原理如下图,通过位图的方式,每个标志(如 O_RDWR、O_CREAT、O_TRUNC 等)都是一个特定的整数值,其中每个标志都使用一个或多个二进制位来表示。因为这些标志的二进制表示互不重叠(即它们的值在二进制上不冲突),可以通过按位或运算符(|)将它们组合在一起。
如:int fd = open("example.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
mode参数: 新建文件的权限
使用: int fd = open(“sfw.txt”, O_WRONLY|O_CREAT, 0666);
最后文件的权限是664,这是由于权限掩码的影响
返回值:文件描述符
后文会详细介绍,这里就简单认为是为open的文件分配一个id,将这个id作为read和write的参数可以对open的文件进行读写。
read && write
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
使用:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
int fd = open("log.txt", O_WRONLY | O_CREAT, 0666);
char buf[] = "6666\n";
write