在C语言中,我们也学习过对文件进行操作,使用C语言对文件进行读写操作是一个正在运行的进程去访问一个二进制文件,想要访问一个文件,首先需要打开这个文件,不同语言都有对文件操作的接口,但是文件本身是存在于磁盘外设中的,想要从磁盘外设中拿到数据,这是要通过操作系统接手的,因为操作系统管理着整个计算机的软件和硬件,因此,想要从文件中读写数据,一定是有操作系统给出的系统调用接口来完成的。而不同语言对文件的操作都可以归为对这个操作系统给出的系统调用的接口的封装.
我们可以在linux中的帮助手册中看到操作系统给出的文件,操作的接口是open函数,这个函数用于打开一个文件,第一个参数是一个字符串,用于传入打开目标文件的文件名,第二个参数是一个整形,第三个于是一个整形,第二个参数用于传入打开文件操作的操作方式,包括读写或者追加,操作系统对于文件是有权限管理的,因此第三个参数,是用来创建一个文件的创建权限,Linux中定义了很多宏,例如O_RDONLY,O_WRONLY,这些宏都是一个标记位,表示打开文件用什么方式打开,与之前用到的waitpid中第二个参数相似,打开方式的参数是一个整形,因此它有32个比特位,而系统给出的宏封装,他们本质是一个16进制数,这类数所有比特位中只有一个位置是1其他都是0,因此他们被用于宏定义标记位,用于传参,他们彼此做按位或运算的结果不会重叠.
Open函数调用成功后返回一个文件描述符,我们就可以使用这个文件描述符对目标文件进行读写操作,Write向一个文件中写入操作,第一个参数是目标写入文件的文件描述符,第二个参数表示要写入的字符串内容,第三个参数表示写入的数据大小,Read函数也是一个系统调用,使用方法与write相同,用于对文件的读取参数规格也与write相同,在C语言中,对于一个字符串的结尾是用零来表示的,而操作系统并没有如此的规定,因此在使用write和read进行数据写入时,需要控制反\0的位置,以及是否需要写入\0,还有需要注意的是,当一个文件被打开后,它的文件指针是指向最开始的位置,当写入以后,如果马上读取,那他的文件指针位置如果没有回位的话,读取的内容是空的,如果想要立即读取,那么可以用lseek系统调用,将文件的文件指针指向文件最开始的位置,再读取就会读取到刚刚写入的内容了.
一个进程可以打开多个文件,打开的每个文件都会有一个文件描述符,并且每打开一个文件都会被加载到内存里,且被合适的数据结构管理起来,PCB进程控制块中有一个结构体,这个结构体中有一部分内容就是有一个文件描述符表,当一个文件被进程打开后,会被这个进程的PCB控制块中的文件描述符表中的指针指向这个文件的属性结构体,然后通过文件描述符表的下标来对文件进行操作,当一个进程打开一个文件时,它自动分派文件描述符表中可用空间的最小值,且往往最小值是3,因为当一个进程被打开,它默认打开键盘显示器和显示器,零号文件描述符表示标准输入,一号文件描述符表示标准输出,二号文件描述符表示标准错误.
也不一定,012都表示这些外设,因为可以有文件描述符的重定向系统调用来重新让这些文件描述符中的指针指向其他的文件,这个系统调用叫dup2,表示将一个文件描述符下表表示的指针和内容复制到另一个文件描述符下表所指向的内容中:
dup2的使用方法是例如 dup2(fd,1);
这句语句表示将原本进程的标准输出重定向到fd文件描述符对应的打开的文件中.
因此我们可以想象到在命令行中使用<,>,>>重定向操作本质是是由解释器调用子进程,对子进程的文件描述服务进行重定向来实现的,具体实现过程是首先对于命令的输入进行判断是否有重定向字符,如果有,则使用dup2系统调用,对子进程的文件描述符进行重定向,使其指向需要指定文件的文件描述符下的指针,子进程对文件描述符的重定向并不会影响到父进程,文件被加载到内存会被文件描述符所管理,因为子进程的独立性,所以父进程在创建子进程时PCB控制块中的文件描述符表也会被复制一份给子进程,然后再进行程序替换,因为程序替换只是让页表中的内存映射发生变化,因此不会影响到文件描述符表,他们虽然都在进程的PCB控制块中,但是并不在一个位置,程序替换只影响进程的地址空间.
在linux中打开一个硬件IO与软件文件,使操作系统都会有一个文件结构体,将他们抽象成统一的模块,并组织管理起来。这个文件模块结构体中有一个读写方法的指针,若文件是真正的软件,文件则使用操作系统的读写方法实现,然后被读写指针所指向。如果对象是硬件外设,则每个硬件外设都有对应的驱动程序,驱动程序中实现了外设中的读写方法,然后这些读写方法会被文件结构体中的读写方法指针所指向,这就达到了linux操作系统对软件和硬件读写统一的管理作用.
标签:文件,操作系统,读写,基础,描述符,io,linux,进程,打开 From: https://www.cnblogs.com/qjwxlj/p/18227345