【Linux】认识文件(一):文件标识符
- 一.什么是文件?
- 1.文件的本质
- 2.文件的分类
- 二.访问文件操作
- 1.C语言中的访问文件接口
- i.fopen
- ii.fclose
- iii.fwrite
- 2.系统访问文件接口
- i.open
- ii.close
- iii.write
- 三.文件管理
- 1.对所有打开文件的管理
- 2.进程对自己打开的文件的管理
- 文件标识符【FD】
本人摸了快四个月的鱼,最近终于开始重新学习了,最近学习了文件的部分内容。
一.什么是文件?
1.文件的本质
用了计算机这么多年,文件应该算是再熟悉不过了
通俗的讲文件就是就是用来存储的
那文件是由什么组成的?
文件=文件内容+文件属性
由这个组成其实我们就能知道文件的本质其实就是数据
内容和属性本质都是用数据存储的。
2.文件的分类
这里我们可以将文件分成两类:打开的文件 和 未打开的文件
可能有人好奇,为什么这个也能成为分类的依据
这里用两个问题来解决大家的疑惑:
1.文件是谁进行打开的?
2.没打开的文件存储在哪里?
第一个问题
:
大伙可能会回答文件是由系统打开的
确实没错,但是范围太广了
就好像问:学生是谁教的,回答是学校
范围太广了,准确来说是老师教的。
所以文件由系统打开,这个答案过于广,准确来说其实是进程来打开的。
那么进程是在哪里进行运行的?
答案是内存
第二个问题
:
很简单,答案就是存储器中,就当它是在硬盘中吧。
所以说靠打开的文件和未打开的文件
进行分类
其实就是分成了内存中的文件和硬盘中的文件
针对两个类型的文件 ,这里也能探究不同的问题
1.打开的文件->进程 :研究进程和文件的关系
2.没打开的文件->磁盘:如何将文件放置好,如何快速进行增删查改,所以本质考虑的是存储
这次主要探究的是:对进程中的文件的操作和管理
二.访问文件操作
这次也不是重点讲文件操作的
所以不会讲的太过于细致 这里就带大家使用几个接口,让大伙见见猪跑就行了。
1.C语言中的访问文件接口
i.fopen
如果想在C语言中进行文件操作
通常的第一步是使用fopen函数打开对应文件
fopen函数用于:
在指定的文件路径上打开文件,并返回一个指向FILE
结构的指针
这里要注意:FILE 是C语言中自己封装的结构体,和系统无关
以便后续对文件进行读取或写入操作。
第一个参数 filename就是文件名
第二个参数则是文件的打开方式
文件打开的方式不同,代表的是给进程的文件的操作方式不同:
“r”:以只读方式打开文件。
“w”:以写入方式打开文件。如果文件不存在,则创建新文件。如果文件已存在,则截断文件内容为零。
“a”:以追加方式打开文件。如果文件不存在,则创建新文件。如果文件已存在,则将写入的数据追加到文件末尾。
ii.fclose
fclose其实就是和fopen对应的
fclose会将打开的文件进行关闭
关闭的过程
:
1.将缓冲区中没有给的数据传给文件
【这里的缓冲区在之后的博客的中会详细讲解】
2.释放文件相关的资源:关闭文件后,fclose函数会释放与文件相关的内存和其他资源。
3.最后返回整数,回报用户是否关闭成功。
iii.fwrite
- ptr:指向要写入的数据块的指针。
- size:每个数据项的大小(以字节为单位)。
- count:要写入的数据项的数量。
- stream:指向要写入的文件的指针。
使用:
运行前:
运行后:
这里我们就能看到,运行代码后
创建了原本不存在的test.log
并且输入了对应的文字
注意小点:
fwrite时,strlen不需要+1
因为字符串以\0结尾时C语言的规定,不是文件中的文本规定
所以写入时,不需要将\0进行写入
2.系统访问文件接口
文件在磁盘上,磁盘时外部设备,访问磁盘文件其实就是访问硬件
我们要把这个给理解了
所以按照我们以前的知识(以前博客写的)
因为系统不相信普通用户
用户在调用硬件的时候,必须经过操作系统来调用硬件
所以几乎所有的库,只要是访问硬件设备,都要对调用函数进行封装
所以fprintf,fwrite,fclose都是经过系统接口的封装得来的C接口
所以不管其他语言的文件操作有多么不同,封装的系统接口都是一样的,万变不离其宗
这里我们就挑几个系统访问硬件的接口来见见猪跑
i.open
注意:
在谈各个参数之前首先注意一下它的返回值:
相比于fopen返回的FILE
这里返回的是一个整数
其实这个整数就是文件标识符【FD】
这个在下面会详细解释,现在只要知道这个整数是文件标识符就行。
参数列表:
- path:要打开或创建的文件路径。
- flags:表示文件打开的标志和选项,可以使用多个标志进行位运算组合
- 常见的标志有:
O_RDONLY:只读方式打开文件。
O_WRONLY:只写方式打开文件。
O_RDWR:读写方式打开文件。
O_CREAT:如果文件不存在,则创建文件。
O_TRUNC:如果文件存在,将其截断为空文件。
O_APPEND:在文件末尾追加数据。
等等,还有其他可用的标志,请参考相关文档以获取更多信息。 - mode:新创建文件的权限,仅在使用 O_CREAT 标志时有效。它指定了文件的访问权限,通常使用八进制表示,例如 0644【文件执行权限】。
ii.close
同样是和open进行对应的
其中,fd 是要关闭的文件描述符。
返回一个整数值来表示操作的结果。如果成功关闭文件,返回值为 0;
如果发生错误,返回值为 -1
iii.write
其中,各个参数的含义如下:
- fd:要写入的文件描述符。
- buf:指向要写入数据的缓冲区的指针。
- count:要写入的字节数。
ssize_t是返回的一个非负数值,表示实际写入的字节数。
如果返回的值与 count 不同,表示写入过程中可能发生了错误
如果发生错误,可以使用 perror 函数输出错误信息。
使用:
在这里插入图片描述
结果:
三.文件管理
接下来就是这个博客的核心了。
那么打开的文件在系统中是如何被管理的呢?
我们知道
打开文件会被加载到内存中
操作系统内部一定存在大量被打开的文件
所以系统需要对所有打开的文件进行管理
同时:
不光是这个管理
我们要知道,一个进程能打开多个文件
单个进程打开的文件也要进行管理
这边我们就分开来讨论
1.对所有打开文件的管理
首先是对系统打开的所有文件进行管理
这个和以前分析管理进程的结构的步骤一样。
对文件先描述在组织
大致其实就这样的链表结构
将对文件的管理转换到对链接的管理
2.进程对自己打开的文件的管理
接下来是对单个进程打开的文件进行管理
文件标识符【FD】
现在应该知道文件标识符是什么了吧。
文件标识符其实就是这个管理进程打开的文件的数组的下标
所以open返回的整数其实就是这个下标而已。
并没有想象中的那么高大上,单纯只是个数组下标而已