前言
Linux 文件 IO 操作指的是在 Linux 系统上对文件进行读取和写入的操作。它是通过与文件系统交互来读取和写入文件中的数据。
在 Linux 中,文件被视为一系列字节的有序集合,每个文件都有一个相关联的文件描述符,用于标识该文件的唯一标识符。文件 IO 操作允许程序从文件读取数据或将数据写入文件。
文件 IO 操作通常包括以下几个主要方面:
open函数
代码语言:javascript复制int open(char *pathname, int flags); -->#include<unisd.h>
参数: pathname :欲打开的文件路径名 flags:文件打开方式 -->需包含头文件#include<fcntl.h> 选项: O_RDONLY:只读方式打开文件。 O_WRONLY:只写方式打开文件。 O_RDWR:读写方式打开文件。 O_CREAT:如果文件不存在,则创建该文件。 mode:文件的访问权限,常用的 mode 包括: S_IRUSR:用户可读权限。 S_IWUSR:用户可写权限
返回值: 成功: 打开文件所得到对应的文件标识符(整数) 失败: -1 设置errno
代码语言:javascript复制int open(char *pathname, int flags mode_t mode);
参数: pathname :欲打开的文件路径名 flags:文件打开方式 mode:参数3使用的前提,参数2指定了O_CREAT 取值是8进制数,用来描述文件的访问权限 创建文件最终权限= mode & ~umask 返回值: 成功: 打开文件所得到对应的文件标识符(整数) 失败: -1 设置errno
代码语言:javascript复制 1 #include<stdio.h>
2 #include<fcntl.h>
3 #include<unistd.h>
4 int main(void)
5 {
6 int fd;
7 fd= open("./test.cp", O_,0551);
8 printf("fd = %dn" ,fd);
9 close(fd);
10 return 0;
11
12 }
13
close函数
代码语言:javascript复制int close(int fd);
错误处理函数: 与errno相关
代码语言:javascript复制printf("xxx error: %sn",errno);
read函数
代码语言:javascript复制ssize_t read(int fd, void* buf , size_t count);
参数: fd :文件描述符 buf:存数据的缓冲区 count:缓冲区大小
返回值: 0:表示读到文件末尾 成功:读到的字节数 失败:-1,设置errno 如果-1 ,并且erron = EAGIN 或 EWOULDBLOCK,说明不是read失败,而是read再以非阻塞方式读取一个设备文件(网络文件),并且文件无数据
write函数
代码语言:javascript复制ssize_t write(int fd, const void* buf , size_t count);
参数: fd: 文件描述符 buf:待写出数据的缓冲区 count:数据大小
返回值: 成功:写入的字节数 失败: -1 设置 errno
fcntl函数
代码语言:javascript复制int flgs = fcntl(fd,F_GETFL);
flgs|=O_NONBLOCK
fcntl(fd,F_GETFL,flgs); 获取文件状态:F_GETFL 设置文件状态:F_SETFL
文件描述符
PCB进程控制块:本质是结构体 成员:文件描述符表 文件描述符0/1/2/3/4…1023 0–STDIN_FILENO 1–STDOUT_FILENO 2–STDERR_FILENO
阻塞/非阻塞
是设备文件,网络文件的属性
阻塞:当进程调用一个阻塞的系统函数时,该进程被置于睡眠状态,这时内核调度其他进程运行,直到该进程等待的事件发生了,才会继续运行。 与睡眠状态相对的是运行状态,在Linux内核中,处于运行状态的进程分为两种状态:
正在被调度执行。CPU处于该进程的上下文环境中,程序计数器里保存着该进程的2指令地址,通常寄存器里保存着该进程运算过程的中间结果,正在执行该进程的指令,正在读写该进程的地址空间
就绪状态。 此进程随时可以执行,但是当CPU还在执行另一个进程时。该进程就会在一个就绪队列中等待被内核调用
产生阻塞的场景。读设备文件,读网络文件(读常规文件无阻塞概念) /dev/tty --终端文件 open(“/dev/tty”,ORDWR|O_NONBLOCK)设置/dev/tty非阻塞状态(默认为阻塞状态)
lseek函数
代码语言:javascript复制off_t lseek(int fd, off_offset,int whence);
参数: fd:文件描述符 offset:偏移量 whence:起始偏移位置:SEEK_SET/SEEK_CUR/SEEK_END SEEK_SET:从文件开头计算偏移量。 SEEK_CUR:从当前位置计算偏移量。 SEEK_END:从文件结尾计算偏移量。
返回值: 成功:较起始位置偏移量 失败:-1 errno
查看: od_tcx filename 查看文件的16进制 od_tcx filename 查看文件的16进制
应用场景: 1.文化的 读,写使用同一偏移位置 2.使用lseek获取文件大小 3.使用lseek拓展文件大小,要想使文件大小真正拓展,必须要引起IO操作。
传入参数
指针作为函数参数 通常有const关键字修饰 指针指向有效区域,在函数内部做读操作
传出参数
指针作为函数参数 在函数调用之前,指针指向的空间可以无意义,但必须有效 在函数内部,做写操作 函数调用结束后,充当函数返回值
传入传出参数
指针作为函数参数 在函数调用之前,指针指向的空间有实际意义 在函数内部,先做读操作 再做写操作 函数调用结束后,充当函数返回值
stat函数
获取文件属性,(从inode结构体中获取)
代码语言:javascript复制int stat(const char *path, struct stat *buf);
成返回0; 失败返回-1 设置errno为恰当值。 参数1:文件名 参数2:inode结构体指(传出参数) 文件属性将通过传出参数返回给调用者。
lstat函数
代码语言:javascript复制int lstat(const char *path, struct stat *buf);
成返回0; 失败返回-1 设errno为恰当值。