文件和操作系统的关系
操作系统控制进程,文件的打开是在进程中进行。意味着用来控制进程的PCB必然有文件的信息,操作系统通过控制PCB的信息来控制文件的读写。
Q1:如何证明文件打开是在进程中进行?
编写c文件调用fopen来操作文件,c文件会被编译成可执行程序执行,即进程,实现进程中对文件操作。
C的文件操作和系统调用
文件调用必须通过系统调用
fopen,fclosed等库函数是用户接口,从硬盘读取文件时,对硬件操作时,必须调用操作系统的函数底层
文件操作库函数和底层函数的关系
c文件操作库函数主要有fopen,fclose等
其中fopen第一个参数是文件名,第二个参数是打开模式
r:只读
r+:可读可写
w:只写,清空再写
w+:可读可写,清空再写,文件不存在创建
a:只写,追加写
a+:可读可读写,追加写
系统调用则用open函数
其中 open函数中的 flags参数表示选项, mode表示文件权限
flags参数表示文件操作读,写,可读可写,参数是宏
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
//设置掩码为0
umask(0);
//创建只写文件,如果文件不存在时创建,新文件掩码是0666
int fd=open("log.txt",O_CREAT|O_WRONLY,0666);
// 关闭文件
fclose(fd);
return 0;
}
因此我们可以推断 fopen的w+模式 必然是对open的封装,且对应的宏参数为O_WRONLY|O_CREAT|O_TRUNC
而不同的模式对应不同的宏参数组合。
宏参数控制的方法叫做比特位控制法
#define ONE (1<<0) #define TWO (1<<1) #define THREE (1<<2) #define FOUR (1<<3) void show(int flags) { if (flags&ONE) printf("hello function1"); if (flags&TWO) printf("hello function2"); if (flags&THREE) printf("hello function3"); if (flag&FOUR) printf("hello function4"); } int main() { show(ONE); ShoW(TWO); show(ONE|THREE); // function3 和function1都打印 return 0; }
文件调用本质
在task_struct的指针中有files_struct的指针
files_struct结构体含有一个数组,数组中有file*指针,数组的下标就是fd,open的返回值file descriptor。
fd为1和为2都指向显示器文件,用引用计数解决这个问题。
file指针管理着文件,包含基本信息
关闭文件就是引用计数减一,同时释放file结构体
在Linux下一切皆文件
fd=0 stdin流,对应键盘文件
fd=1 stdout流 对应显示器文件
fd=2 stderr 显示器文件
向fd为1的文件,即向显示器输出hello Linux。
C语言的FILE* 必然会封装fd
同理库函数的printf等调用fd为1的文件。