1 文件描述符和打开模式
1.1 文件描述符
文件描述符fd:
- 是一个>=0的整数。
- 每打开一个文件,就创建一个文件描述符,通过文件描述符来操作文件。
预定义的文件描述符:
- 0:标准输入,对应于已打开的标准输入设备(键盘)
- 1:标准输出,对应于已打开的标准输出设备(控制台)
- 2:标准错误, 对应于已打开的标准错误输出设备(控制台)
多次打开同一个文件,可得到多个不同的文件描述符。
fd本质为特殊的索引,实际上就是进程中file_struct结构体成员fd_array的数组下标。

1.2 文件打开模式
主模式:
- O_RDONLY:只读模式
- O_WRONLY:只写模式
- O_RDWR:读写,模式
副模式:
- O_CREAT:当文件不存在,需要去创建文件
- O_APPEND:追加模式
- O_DIRECT:直接IO模式
- O_SYNC:同步模式
- O_NOBLOCK:非阻塞模式
- O_EXCL:如果同时使用O_CREAT而且该文件又已经存在时,则返回错误, 用途:以防止多个进程同时创建同一个文件
- O_TRUNC:若文件存在,则长度被截为0,属性不变
2 open
头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型:
-
当文件存在时
int open(const char* pathname,int flags) -
当文件不存在时
int open (const char* pathname,int flags,int perms)
上面的两个函数实际上是使用可变参数。
当其第二个参数含有O_CREAT 时,第三个参数才有效。表示的是当使用open系统调用创建一个文件时,其文件的访问权限是多少,第三个参数可以指定为0755,0644等,也可以用系统提供的宏:S_IRWXU、S_IRUSR等代替,一个作用。
返回值:
- 成功:文件描述符
- 失败:-1
注意:返回的文件描述符是该进程未打开的最小的文件描述符。
3 close
头文件:
#include <unistd.h>
函数原型:
int close(int fd)
返回值:
- 成功:0
- 失败:-1
4 read
头文件:
#include <unistd.h>
函数原型:
ssize_t read(int fd,void *buff,size_t count) // ssize_t是有符号数
返回值:
成功:
- count:成功读取全部字节
- 0~count:
- 剩余文件长度小于count
- 读取期间被异步信号打断
失败:
- -1,读取错误
5 write
头文件:
#include <unistd.h>
函数原型:
ssize_t write(int fd,void *buff,size_t count)
返回值:
成功:
- count:成功写入全部字节
- 0~count:
- 写入期间被异步信号打断
失败:
- -1,读取错误
复制普通文件小实验:
1、打开要复制的文件
2、创建新的文件
3、把源文件内容读到缓冲区,把缓冲区内容写入新文件
4、循坏执行第三步,直到读取的字节数量为0,退出循坏。
5、关闭打开的文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int fd1 = -1, fd2 = -1;
int read_len = 0;
char buffer[512] = {0};
if (argc != 3)
{
printf("error usage !\n");
return -1;
}
fd1 = open(argv[1], O_RDONLY);
fd2 = open(argv[2], O_WRONLY | O_CREAT, 0666);
if ((fd1 < 0) || (fd2 < 0))
{
close(fd1);
close(fd2);
printf("open file error!\n");
return -1;
}
while (1)
{
read_len = read(fd1, buffer, sizeof(buffer));
if (read_len <= 0)
{
break;
}
write(fd2, buffer, read_len);
}
close(fd1);
close(fd2);
return 0;
}
6 lseek
功能:
- 设置文件读写位置
头文件:
#include <unistd.h>
函数原型:
off_t lseek(int fd,off_t offset,int whence)
- 若whence为SEEK_SET,基准点为文件开头
- 若whence为SEEK_CUR,基准点为当前位置
- 若whence为SEEK_END,基准点为文件末尾
返回值:
- 成功:文件偏移位置值
- 失败:-1
读写是使用的同一个位置指针。使用O_RDWR时,如果先读了一段再写,那么写的位置从读完处开始,同理先写了一段再读,那么读的位置从写完处开始。可以使用lseek来改变文件位置指针,即读写的位置。
7 sync

功能:
- 页缓存和回写,强制把修改过的页缓存区数据写入磁盘。
头文件:
#include <unistd.h>
函数原型:
void sync(void);
返回值:
- 无
8 标准IO函数
由于系统文件IO函数需要在用户态和内核态之间进行切换,所以效率比较低。标准IO则在应用层实现了一个缓冲区,示意图如下:

常见标准IO函数:
-
fopen
-
fclose
-
fread
-
fwrite
-
fseek
-
fflush:强制把IO缓存区的数据写入到页缓存区
文件IO五大模式:
- 阻塞模式
- 非阻塞模式
- IO多路复用
- 异步IO
- 信号驱动IO
参考资料:
1278

被折叠的 条评论
为什么被折叠?



