Linux系统编程之文件操作问题补充
前言
此篇文章对文件系统原理的阐述,仅涉及读写打开关闭的原理简述,特别是对于文件描述符、文件读写和存储、close函数的补充。一、简述
在linux中要操作一个文件,一般先用open打开一个文件,得到其文件描述符fd,然后才是对文件的读写操作或者其他操作,最后是close关闭文件
二、文件类别
1.静态文件
平时存放在块设备中的文件系统中,比如存储在硬盘上面的文件
2.动态文件
内核在内存中申请一段内存,并且将静态文件从块设备中读取到内核中特定地址管理存放,这样的由静态文件所变的文件叫做动态文件
三、文件操作问题补充
1.对文件描述符 fd补充
1.对于内核而言文件描述符都是打开文件的引用,是一个非负的整数。
2.Unix shell使用文件描述符0与进程的标准输入相结合,文件描述符1与标准输出相结合,文件描述符2与标准错误输出相结合。STDIN_FILEND、STDOUT_FILEND、STDERR_FILEND这几个宏分别代替0、1、2
3.文件描述符只在一个进程中有特定的含义,当open一个文件时,操作系统在内存中构建了一些数据结构,如结构体类型数据,然后才给应用程序返回一个数字称之为文件描述符
4.文件描述符与这个文件的数据结构相绑定,对动态文件区分,就只需对文件描述符区分
5.文件描述符的作用于仅在当前进程,进程结束或者在进程之外,文件描述符无任何意义。
2.对文件读写和存储补充
1.文件描述符中我们说到,当open一个文件时,操作系统在内存中构建了一些数据结构,如结构体类型数据。那么这个数据结构是用来干嘛的呢?对其分析之后,我们明白了它是用来存储相应的静态文件名、动态文件名、文件内容、标识符等等一些信息
2.在Linux系统中,我们平时所说的文件都是静态文件,它都是存储在块设备中的文件系统中,当用open打开一个文件,内核才会向内存申请一段内存来形成动态文件,那么为什么要这样设计呢?而不是直接对静态文件操作?
通过分析,我们知道 Linux的块设备(磁盘)中,对文件的内容是按块读取,而不是按字节读取,而内核中所申请的内存,对文件的读取是按字节单位操作,而且可以随机操作。两者相比,块设备对文件的读取显得非常不灵活。
比如:我们想要修改一个字节或者少数字节内容时,若块设备一块为100字节大小,那么只能同时对100字节内容进行修改,而不能修改其中个别字节内容。
又因为块设备存储空间相对较大,可以存储的数据量大且不易丢失损坏且容易查询,而内存空间相对较小,可以存储的数据量小、易丢失损坏且不容易查询,所以这就是为什么对文件读取时,内核要将块设备中的文件转换到内存中去,而之后又要再转换为静态文件。
3.对close()函数的补充
在“对文件读写和存储补充”中,我们简述了读取文件时,内核对文件操作的原理和原因。在写程序时,我们发现加不加close()函数,系统终端都不会报错。那么这个close()函数是不是多余的呢?
通过多次测试和对不同程序的比较,我们发现在open打开文件之后,对文件的读写操作都是建立在内存中动态文件上,而不是针对静态文件的,当我们对动态文件进行操作时,静态文件并不会有数据变化,即内存中的动态文件和块设备中的静态文件不同步。当我们使用close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)到块设备中的静态文件。除此之外,使用close()函数之后,会完整保存文件内容,防止了文件的损坏和数据丢失。
四、总结
增强编程能力,光看不行,动手最关键,最后总结出一片文章记录自己的学习过程。