目录
文件I/O
文件IO又称系统IO,所以是unix内核向上提供的io操作的函数,都是系统调用函数
1.1 系统调用和库函数
- 库函数是在系统调用的基础之上再次根据不同的需求进行封装的
例如:fgetc(3) getchar(3) fgets(3) fread(3)他们都是通过调用系统调用的read(2)而实现的- 系统调用依赖操作系统,所以是不能跨平台的,而库函数是标准库,所以可以跨平台的
1.2 标准IO与系统IO
- 标准io是有缓存区的,合并系统调用的次数,提高程序的效率
- 系统io是没有缓存区的,每次调用都是实实在在的向内核态切换
1.3 打开文件 open()
文件描述符:非负整型数,是文件io打开文件的标志。使用规则是当前可用最小作为新打开文件的文件描述符
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
function: 打开指定文件
pathname: 要打开文件的路径
flags: 打开文件的方式
打开文件的方式
- O_RDONLY O_WRONLY O_RDWR这个中方式必须三选一
- 附加选项有O_CREAT O_TRUNC O_APPEND 等
- 位图:用一个整型数的二进制某一位或者某几位表达一种状态,例如flags就是一种位图的应用
- O_WDONLY表达只写,O_CREAT表达创建,O_TRUNC表达截断
- O_WRONLY | O_CREAT | TRUNC就是表达只写的方式打开,不存在则创建,存在则截断
1.4 读文件 read()
ssize_t read(int fd, void *buf, size_t count);
fd是文件描述符,要读的已打开的文件
buf:存储读到的内容
count:最多读取的字节个数
返回值 :
1. 成功:读到的字节个数
2. EOF:返回0
3. 失败:-1
1.5 写文件 write()
ssize_t write(int fd, const void *buf, size_t count);
fd要写的文件
buf准备要写入文件的数据
count:要写入的字节个数
返回值:
1.成功:写入的字节个数
2.失败:返回-1
1.6 定位 lseek()
off_t lseek(int fd, off_t offset, int whence);
fd要写的文件
offset偏移的位置
whence插入的位置
1.7 关闭文件 close()
int close(int fd);
拓展
UBUNTU登录成功后,以下三个文件就打开了
1.标准输入 0 stdin(FILE *)
2.标准输出 1 stdout
3.标准错误输出 2 stderr关于EOF
1.文件末尾标志
2.错误标志
if(n == EOF)
{
if(feof(xxx))
puts("文件已经到末尾了");
else if(ferror(xxx))
puts("文件读到错误了");
}
1.8 三张表结构
内核为打开的文件维系的三张表结构:进程表项、文件表、i结点表
1.9 异常的提示
errno
是一个全局整型变量(errno.h)不同的值表示函数调用的不同出错状态
默认值为0的时候是成功的 [sucess]
errno > 0 出错
- strerror(3) 根据errno的值返回出错原因字符串 如strerror(errno);
- perror(3) 直接打印出错原因 如 perror(“ ”);
大部分的系统调用函数和部分库函数,在函数出错的时候会设置errno
注意:不是所有的函数出错都设置了errno,具体一定遵循手册
1.10 文件描述符的复制 dup(2)
dup(2)
int dup(int oldfd);
复制oldfd,使用当前可用最小最为oldfd的复制
dup2(2)
.
int dup2(int oldfd, int newfd);
newfd作为oldfd的复制,如果newfd已经被占用,则关闭后作为oldfd的复制
1.11文件重定向
dup(2) / dup2(2)
习题一
digit1 > &digit2 【dup2(digit2, digit1)】
> 标准输出重定向 1>
2> 标准错误输出重定向
./a.out > outfile 2 > &1
./a.out > outfile (fd) 【dup2(fd, 1)】
2 > &1 【dup2(1, 2) 】
1 2 都重定向到outfile
./a.out 2>&1 > outfile
./a.out 2 > &1 【dup2(1, 2)】
> outfile 【dup2(fd,1)】
2重定向到标准输出
1重定向到outfile
fcntl在复制文件描述符的时候与dup2有差异
fcntl在复制的时候如果newfd被占用,那么当前可用最小作为oldfd的复制
dup2在复制的时候如果newfd被占用,那么会关闭再复制