继上文的标准IO的详细讲解,本文将继续为大家介绍文件的操作第二部分文件输入输出操作,跟标准IO的学习习惯相同我们也从打开、读写、关闭文件,这个思路对于文件的IO的各个函数接口进行具体的详解。
文件IO函数接口学习思路:
- 打开文件-----open
- 读写文件-----read,write
- 关闭文件-----close
在具体讲解文件IO的各个函数接口之前想为大家介绍一下文件描述符这个新概念
- 文件描述符是很小的非负的整数 int 0到1023
- 内核每打开一个文件就会获得一个文件描述符
- 新生成的文件描述符永远为最小的非负整数
- 每个程序在启动的时候操作系统默认为其打开三个描述符与流对象匹配:
- 0 ==>STDIN_FILENO === stdin
- 1 ==>STDOUT_FILENO == stdout
- 2 ==>STDERR_FILENO == stderr
1.打开文件
函数接口:open
int open(const char *pathname, int flags); //打开一个已有文件
int open(const char *pathname, int flags, int mode);
作用:
- 使用文件描述符描述一个文件
参数:
- pathname:文件名
- flags:
- 必须项:他们之间是互斥的,所以有且只能有一个
命令(flag) 命令意义 类似于 O_RDONLY 只读命令 “r” O_WRONLY 只写命令 / O_RDWR 读写命令 “r+” - 可选项:(如果有可选项的命令则需要添加mode参数)
命令(flag) | 命令意义 |
O_CREAT | 创建文件,若文件存在只作打开操作 |
O_TRUNC | 文件内容清空 |
O_APPEND | 追加方式 |
不常用 | |
O_NOCTTY | 不是终端设备 |
O_ASYNC | 异步io,什么时候io不确定 |
O_NONBLOCK | 非阻塞 |
- mode:关于mode参数的详细讲解我将在后续的文章中单独讲解,本文及后面默认mode为0664的功能
返回值:
- 成功返回文件描述符 (最近最小未使用)
- 失败返回-1
代码展示
int main(void) { int fd = open("1.txt", O_WRONLY | O_CREAT |O_TRUNC, 0664); if(fd == -1) { printf("Fail to open.\n"); return -1; } printf("%d\n", fd); close(fd); return 0; }
以上运行代码的fd的返回值为3,由一开始对于文件描述符的讲解,这里我们可以看出在系统自动定义的文件描述符0,1,2之后最小的未被占用的文件描述符为3,那么我们这个指向1.txt的文件描述符则为运行结果3,那么证明已成功获取一个文件描述符描述该文件。
2.读文件
函数接口:open
ssize_t read(int fd, void *buf, size_t count);
作用:
- 通过文件描述符读取文件中的数据
参数:
- fd:文件描述符
- buf:存放数据空间的首地址
- count:要读到数据的个数
返回值:
- 成功返回读到数据的个数
- 失败返回-1
- 读到文件结尾返回0
代码示例
int main(void) { int fd = open("1.txt", O_RDWR); if(fd == -1) { printf("Fail to open.\n"); return -1; } char buff[1024] = {0}; ssize_t ret = read(fd, buff, sizeof(buff)); printf("ret = %ld\n", ret); puts(buff); close(fd); return 0; }
运行结果为ret=12,并且输出的buff里面为我原来在1.txt的文件里面保存的Hello World的字符串,来证明read的操作成功。
注意:read不给数据加‘\0’
3.写文件
函数接口:write
ssize_t write(int fd, const void *buf, size_t count);
作用:
- 通过文件描述符向文件中写一串数据
参数:
- fd:文件描述符
- buf:要写入文件的字符串的首地址
- count:要读到数据的个数
返回值:
- 成功返回读到数据的个数
- 失败返回-1
代码演示
int main(void) { int fd = open("1.txt", O_RDWR | O_CREAT |O_TRUNC, 0664); if(fd == -1) { printf("Fail to open.\n"); return -1; } char buff[] = {"Hello World"}; ssize_t ret = write(fd, buff, strlen(buff)); printf("ret = %ld\n", ret); close(fd); return 0; }
程序运行的结果为ret = 11,那就说明数组buff中的内容完整的保存进了1.txt的文件中,后续我在1.txt中也看到了正常保存进去。
4.关闭文件
函数接口:close
int close(int fd);
作用:
- 关闭文件描述符
参数:
- fd:文件描述符
同标准IO一样,文件IO打开文件描述符也要记得关闭,因为局部变量申请内存空间在栈上,申请以后要记得释放,否则后续文件过多时就会产生栈溢出问题。
以上便为文件IO的基础的输入输出的函数接口,在后续的文章中会对文件IO的接口进行补充,lseek等,并且为大家介绍目录IO的各个函数,如果有问题请在评论区评论或者私信我,大家共同讨论进步!