目录
前言
回顾C语言的操作
Q1
Q2
Q3
C语言文件操作
w方式
a方式
重定向和"w""a"方式
前言
前面进程虚拟地址空间让我们对进程的理解更加深入。在基础IO我们会详细介绍文件和文件系统。本专题的核心内容是文件。
- 深刻理解文件(站在OS的角度)
- 深入理解重定向和缓冲区
- 学习文件系统(磁盘文件和经典的文件系统结构)
- 以及动静态库制作和使用,yum源的配置等操作。
回顾C语言的操作
❓在C语言阶段,我们学习了C语言是如何打开/关闭/写入/读取文件的。我们仅仅是在语言层面上学会了对文件的操作接口。不仅C/C++/Java等其他语言都有文件操作接口,文件操作都不一样,为什么不一样。
❓是否我们站在OS的角度就可以理解文件。
请看以下代码☞,思考下面问题:
1: testfile.c
1 #include<stdio.h>
2 int main()
3 {
4 FILE *fd = fopen("log.txt","w");
5 if(fd == NULL)
6 {
7 perror("fopen");
8 return 1;
9 }
10 fclose(fd);
11 return 0;
12 }
//运行可执行程序,文件不存在,OS默认创建在当前目录下
【文件指针FILE】
【perror】
Q1
❓创建一份C语言的文件时,并没有指明文件的具体路径,代码中只是告知文件名,OS怎么知道当前创建的文件在我们想要的路径下呢。
回答:因为我们在运行我们的程序的时候,执行打开文件操作的代码的时候。 程序已经变成一个进程。所以我们创建log.txt文件时,默认会结合当前进程所在路径创建,所以如何没有路径给到OS,那么OS会结合进程当前所在路径去创建log.txt。
❓我们写完文件操作的代码,fopen文件就算被打开了吗。
回答:文件操作的代码写完了。但是不编译运行。文件根本没有被打开。我们要进行文件操作,前提是我们的程序跑起来了,成为进程了。文件打开和关闭,是CPU在调度我们的进程,正好执行到fopen和fclose代码。打开文件的本质其实是进程打开文件!!
【进程在启动时所处的路径叫进程的当前工作路径】
Q2
❓文件没有被打开的时候在哪里。在磁盘上
❓一个进程能打开很多文件吗。可以
❓系统中能存在很多进程吗。很多情况下,在OS内部,一定存在大量的被打开的文件。
❓OS需要对大量的文件做管理吗。肯定的。
没有被打开的文件在磁盘(硬件上),如果需要打开文件,就需要访问硬件。硬件的管理者是操作系统。一定是OS打开文件。OS打开大量的文件,就需要把这些打开的文件进行管理。(管理的六字真言:先描述再组织)
❓先描述再组织。意味着:在OS内部,也要创建文件对应对象-内核数据结构,打开文件,创建数据结构,形成很多文件对象。最后以链表的形式管理起来。对文件的管理,变成对链表的增删查改。(每一个被打开的文件,在OS内部,一定要存在对应的描述文件属性的结构体。类似PCB)
- struct PCB(task_struct):可执行程序加载到内存中,可执行程序的内核数据结构
- struct RunQueue:硬件有对应的等待队列
- struct file:文件也有对应的内核数据结构(存放文件属性)
- OS内核中一个被打开的文件本质一定是一个文件对象或者一个结构体类型的对象。
- struct task_struct☞struct file两种对象之间的指针关系
Q3
❓新建一个大小为0的文件在磁盘需不需要占据磁盘空间。(文件没有打开,没有在内存中,在磁盘中)
回答:要占磁盘空间。文件名/时间/类型/大小/权限等文件属性等都是数据,需要占据磁盘空间。文件 = 文件属性 + 文件内容
C语言文件操作
w方式
以w方式打开文件。
- w方式的特点:
- 文件存在,就清空写入
- 文件不存在,在当前进程的工作目录路径下创建,写入。
- 默认打开文件的时候,就会先把目标文件清空!
- 写入库函数接口:fprintf
- man fprintf
- int fprintf(FILE *stream, const char *format, ...);
- FILE *stream:写入指定的文件
- const char *format, ...:以指定格式把指定内容写入
- w Truncate file to zero length or create text file for writing.
打开创建当前文件。进程被调度,执行到代码语句的时候,才会打开,写入,判断,关闭等系列文件操作(进程被调度)。里面含有/proc进程的当前工作路径。
【文件存在,就清空写入】
【清空实验】
在存在log.txt文件且log.txt内容存在的情况下。只有打开,没有写入和关闭。我们再以w的方式打开一次文件。
原log.txt存在数据,但再以写的方式打开一次(只打开)。文件仍然存在,默认文件的内容被清空。在C语言,以w属性打开文件,文件打开即清空。
【文件不存在,在当前进程的工作目录路径下创建,写入】
a方式
以a方式打开文件。
- a方式的特点:
- 文件存在,就不清空写入
- 文件不存在,在当前进程的工作目录路径下创建,写入。
- 默认打开文件的时候,就不会先把目标文件清空!
- 文件存在且有内容的情况下,重新打开文件,写入。w方式一定会清空文件再写入;而a方式不会清空直接追加。
- appending追加:追加的本质也是写到文件的结尾。
【文件存在,就清空写入】
【文件不存在,在当前进程的工作目录路径下创建,写入】
重定向和"w""a"方式
重定向回顾:
使用重定向可以极大地提高Linux命令行操作的灵活性和效率,尤其是在脚本编写和自动化任务中。
请看下面代码☞:
- echo "hello linux" Linux当中一切皆文件默认向显示器文件stdout打印
- > 输出重定向本质就是把向显示器文件写入的数据,重定向向log.txt文件写入
- 经过重定向变成了本来应该向显示器打印的内容,写入了磁盘文件中
- 经过上面分析,我们猜测重定向一定伴随文件操作或者和文件操作有关。
- 输出重定向一定是文件操作!
- > 的特点:每次写入文件的数据都是存在文件,清空写入;不存在,创建写入。(每次写入都要清空)
- 所以,推测> 是以 "w" 方式把文件打开。
- > 可以用来新建文件,清空文件。(不存在就创建。先清空,再写入)
- >> 的特点:存在文件,不清空写入;不存在,创建写入。
- 所以,推测>> 是以"a"方式把文件打开。
【>】
【>>】
🙂感谢大家的阅读,若有错误和不足,欢迎指正。