Linux操作系统应用编程——文件IO
前面已经说了,012自动占了三个文件标识符位置,所以若要向终端写入数据时,则不需要额外打开,只需要将fd位置改为1即可,而此时终端为输出设备,判断输入输出的对象是内存,从内存中出来为输出,存入内存中是输入。与标准IO的区别在于,标准IO操作的是文件流指针FILE*,文件IO操作的是文件描述符,而且这个文件流指针FILE指向一个复杂的结构体,结构体中含有文件描述符。对于部分大文件,需要反复读取,如果
文件描述符
文件描述符:操作系统中已打开文件的标识符,是小的、非负的整型数据
范围:0-1023(共1024个)
分配原则:最小未被使用原则,而系统默认已经打开的三个文件占用了0、1、2这三个文件描述符,所以先分配3,再4

与标准IO的区别在于,标准IO操作的是文件流指针FILE*,文件IO操作的是文件描述符,而且文件流指针FILE指向一个复杂的结构体,结构体中含有文件描述符
文件描述符泄漏:已打开的文件,使用完时,未及时关闭
进程结束时候会关闭打开的所有文件描述符
操作函数
open




需包含额外头文件
功能:打开文件并获得一个文件描述符
参数:
pathname:要打开的文件的文件名
flags:打开方式


其中的|为按位或的运算符
mode:对文件的操作权限,为八进制数,对应的权限,有则为1无则为0
| 操作权限 | rwxrwxrwx | rw-rw-r-- |
| 对应二进制 | 111111111 | 110110100 |
| 对应八进制 | 0777 | 0664 |
然而,就算mode为0777,最后一组rwx也不会完整,因为被创建的文件mode会与掩码值的反码进行位运算,得出一个新的mode值
值得注意的是,第一个open函数不能用于创建文件,即只能用于操作已存在的文件,如果通过其创建文件,则不存在的第三个参数会变成随机数,即创建出的文件会是一个随即权限

返回值:成功则为文件描述符,失败则为-1


只读方式需要文件存在才可读,所以一开始会报错,创建后才成功。由于文件描述符最多为1023,所以打开完文件后要及时关闭,避免造成文件描述符泄漏


文件描述符的范围从3开始到1023,超过范围则打开失败从而返回-1
close

需包含头文件
功能:关闭文件
参数:文件标识符


经过close关闭的文件,其文件描述符也会被回收
write

![]()

需额外包含头文件
功能:向文件中写入数据
参数:文件描述符;要写入的数据的首地址;要写入的字节数
返回值:成功则为实际写入的字节数,失败则为-1


前面已经说了,012自动占了三个文件标识符位置,所以若要向终端写入数据时,则不需要额外打开,只需要将fd位置改为1即可,而此时终端为输出设备,判断输入输出的对象是内存,从内存中出来为输出,存入内存中是输入

![]()
read

![]()

功能:从文件中读取数据
参数:文件描述符;存储数据的空间首地址;希望读取的字节数
返回值:成功则为实际读到的字节数,失败则为-1,若是读到文件末尾则为0


当然,read()函数也可以实现通过终端读取数据,如下


空行的原因是因为回车键,即\n也被read读取,而puts会补上一个换行符。在向终端输入数据时,数据会先存放在缓冲区中,直到输入回车(\n)再开始读取,而read便会将缓存区中的数据读出来,直到读到\n或者读完第三个参数个字符,以以下例子为具体讲解
当输入超过read读取的字符数上限时,read只会读取5个,而向缓存区输入了8个,在读取到回车时,便将read未读取的字符输出了出来,包括回车
输入12345时,read只读五个,所以无法读到回车,而输入1234时,read会读到回车,在加上puts填上的换行符,所以会多出一行空行
对于close函数,由于系统会默认使用三个文件描述符,而close也可以关闭这三个描述符,从而使得某些函数失效,例如read


实现cat功能

对于部分大文件,需要反复读取,如果字节数不是缓冲区字节数的整数倍,则会造成越界访问,出现乱码,所以可通过write读写read的返回值

文件定位函数
lseek

![]()


功能:文件读写位置定位
参数:文件描述符;偏移量(字节);要偏移的相对位置

返回值:成功则为当前读写位置到文件开头的偏移量,失败则为-1



openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐




所有评论(0)