文件IO --- 系统调用<fcntl.h>
2.1缓存的设计
缓存设计的目的提高效率本质上来说 --- 缓存其实就是一块内存空间
使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。
缓冲区的大小是可以设置
- Linux 标准 I/O 缓存分三类:交互场景行缓存、文件场景全缓存、出错场景不缓存,适配不同场景的实时性与效率需求;
<是输入重定向(读文件)、>是输出重定向(覆盖写文件),是 Linux Shell 中修改程序 I/O 源的基础用法。

cs
int feof(FILE *stream);
检查函数是否真的到达EOF;如果真的出错,函数返回真
int ferror(FILE *stream);
检查函数是否真的出错;如果真的出错,函数返回真

2.2标准IO和文件IO


库函数: //标准IO 优点: a.方便,功能多 b.可移植性好 标准 不足: c.可能存在 安全性 隐患 系统调用: 优点: a.使用起来,简单 ,功能简单 b.安全性高 c.设备文件 ---- 文件IO ///dev/video0 ----> fopen(); 缺点: c.很多复杂功能需要自己封装设计 d.可移植性差
2.3系统默认打开的文件描述符

-
系统启动后会默认打开这 3 个文件描述符 ,数值
0、1、2是固定且唯一的,不能被随意占用。 -
stdin 负责接收输入、stdout 负责正常输出,而 stderr 是独立的错误输出通道,即使 stdout 被重定向,stderr 仍可单独输出错误信息到屏幕。
-
这三个描述符是 Linux/Unix 系统 IO 操作的基础,所有终端交互的输入输出本质上都是对这三个描述符的操作。
2.3.1打开
open函数
cs
#include <fcntl.h>
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
功能:
打开或创建文件
参数:
@pathname //打开的文件名
@flags //操作的标志,指定访问模式
//必选
O_RDONLY //只读
O_WRONLY //只写
O_RDWR //读写
//附加
O_APPEND //追加
O_CREAT //文件不存在 创建
O_TRUNC //文件存在 截短为0
@mode 一般不用
当flags中使用了 O_CREAT 时,需要指定 mode
mode 0777
0666
0444
返回值:
成功 文件描述符
失败 -1 && errno会被设置

2.3.2关闭
close函数
cs
int close(int fd);
功能:
关闭文件描述符
以便 再次使用
参数:
@fd 要关闭的文件描述符
返回值:
成功 0
失败 -1
文件描述符:
1.非负整型数值
2.分配原则
最小未使用
3.范围
0~1023
2.3.3读写
read函数
cs
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:
从fd中读数据 ,存到 buf中
参数:
@fd 要读取的文件
@buf 存放读取到的数据的 内存空间
@count 一次要读取的数量(字节)
返回值:
成功 表示成功读到的字节数
失败 -1 && errno
读取结束:
0 表示到达文件结尾
write函数
cs
ssize_t write(int fd,const void *buf, size_t count);
功能:
把buf中 写到fd中
参数:
@fd 要写入的文件
@buf 存放数据的 内存空间
@count 一次要写入的数量(字节)
返回值:
成功 表示成功写入的字节数
失败 -1 && errno
2.3.4常用函数
lseek
cs
off_t lseek(int fd, off_t offset, int whence);
功能:
重新定位文件偏移量
参数:
@fd 要定位的文件
@offset 偏移量
@whence 参考点
SEEK_SET //相对于文件开头的
offset >=0
SEEK_CUR //相对于当前位置
offset>=0
offset<0 //不能超过这个文件开头
SEEK_END //相对于文件末尾
offset < 0 //不能超过这个文件开头
offset >= 0 //可以 --- 创建 空洞 文件
返回值:
成功 从头的偏移量
失败 -1 && errno
注意:
1、不支持O_APPEND的追加模式,无法生成空洞文件。
2、lseek函数执行失败,文件指针还在偏移前的位置。
3、lseek函数在设备文件上偏移无效。 /dev/video0
4、fifo,socket 也不支持lseek的操作。
lseek(fd,0,SEEK_SET); //定位到文件开头
lseek(fd,0,SEEK_END);
获得文件长度:
off_t len = lseek(fd,0,SEEK_END); //off_t <=> long int
2.4标准IO操作中 ---系统调用的函数
fdopen()
//将fd 转换 成 FILE *
cs
FILE *fdopen(int fd,const char *mode);
功能:
将fd 转换 成 FILE *
参数:
@fd 要操作fd
@mode 打开的模式
返回值:
成功 FILE *
失败 NULL
fileno()
//将FILE *转换 为 fd
cs
int fileno(FILE *stream);
功能:
将FILE *转换 为 fd
参数:
@stream 要转换流指针
返回值:
成功 fd
失败 - && errno
fd = open(,O_RDONLY);
FILE *fp = fdopen(fd,"a");
int feof(FILE *stream);
int ferror(FILE *stream);