文件I/O
来源:互联网 发布:电脑系统维护软件 编辑:程序博客网 时间:2024/06/02 03:43
print函数
printf函数的调用链: printf write int 0x80 sys_write
printf和write属于用户层函数,int 0x80相当于一闪门,进入到内核函数sys_write。
sys_write 完成后,再一层一层的将结果返回到 printf。
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, mode_t mode);
1、 flags有3个必选项 O_RDONLY、O_WRONLY、O_RDWR。这三个值是互斥的,只能选一个。
2、flags有很多可选项,O_CREAT、O_APPEND、O_EXCL、O_TRUNC、O_NONBLOCK这些值可以多选。不能和必选项发生冲突。
3、若选择了O_CREAT选项、那么open函数第三个参数mode就必须写。O_EXCL只和O_CREAT配合使用,若开启O_EXCL,而且创建的文件存在,函数返回-1。
4、O_APPEND表示追加的方式打开文件。
5、O_TRUNC表示打开文件将长度截取为0。
6、O_NONBLOCK针对设备文件,比如屏幕网络,表示非阻塞方式打开IO。
flag选项示例:
open('test', O_RDONLY); // 只读方式打开open('test', O_WRONLY | O_APPEND); // 追加的方式打开open('test', O_RDWR); // 读写的方式打开open('test', O_WRONLY | O_CREAT, 0666); // 创建文件,只写,权限是 0666open('test', O_WRONLY | O_TRUNC); // 只写打开,同时把文件长度截断成 0.
read函数
//头文件#include <unistd.h>//函数原型ssize_t read(int fd, void *buf, size_t count);返回值:返回读到的字节数,返回0表示读到文件末尾,返回-1表示出错。
write函数
//头文件#include <unistd.h>//函数原型ssize_t write(int fd, const void *buf, size_t count);
返回值 返回写入的字节数,出错返回-1
lseek函数
//头文件#include <sys/types.h>#include <unistd.h>//函数原型off_t lseek(int fd, off_t offset, int whence);
改变文件的当前的偏移量。
当open函数打开一个文件的时候,偏移量默认为0
whence的值: SEEK_SET 文件头部 SEEK_CUR 文件尾部 SEEK_END 文件尾部
阻塞IO
通常情况下,从普通文件传数据,会在有限的时间内返回,如果从设备、网络中读取数据如果没有数据可读read一定会堵塞不会返回。
read的这种行为称为block,一旦发生block进程会被操作系统投入随眠,直到等到事件发生进程才被唤醒。
系统调用write同样有可能被阻塞,比如向网络写入数据,若对方不接收,本端缓冲区一旦写满就会被阻塞。
阻塞IO与非阻塞IO效率
阻塞IO与非阻塞IO的几个问题:
1、阻塞与非阻塞是文件本身的特性,不是系统调用read/write可以控制的。
2、终端默认是阻塞的,我们可以重新open设备文件/dev/tty(表示当前终端),打开时指定O_NONBLOCK标志就行了。
3、非阻塞read,如果有数据到来返回读到的字节数。如果没有数据返回-1。
fcntl函数
//头文件#include <unistd.h>#include <fcntl.h>//函数原型int fcntl(int fd, int cmd, ... /* arg */ );fcntl函数可以修改文件状态位的标志,fcntl函数第二个参数取不同的值有着不同的功能,如果失败返回-1 。
以上函数使用测试代码
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <errno.h>#include <fcntl.h>int main(int argc, char const *argv[]){if (argc != 3){printf("输入参数有误。\n");return 0 ;}int srcfd = open(argv[1],O_RDONLY);//只读方式打开文件perror("open"); if(srcfd == -1){return -1 ;}int dsfd = open(argv[2],O_CREAT | O_WRONLY,0666);perror("open");if (dsfd == -1){return -1 ;}int len = 0 ;char* buff[1024] ;memset(buff,0,sizeof(buff));while(len = read(srcfd,buff,sizeof(buff)) > 0){write(dsfd,buff,sizeof(buff));memset(buff,0,sizeof buff);}lseek(srcfd,-20,SEEK_END);//将文件指针冲文件末尾向文件头部偏移20字节read(srcfd,buff,sizeof buff);write(STDOUT_FILENO,buff,sizeof(buff));close(dsfd);//关闭文件close(srcfd);//阻塞I0实验write(STDOUT_FILENO,"阻塞实验开始\n",sizeof("阻塞实验开始\n"));memset(buff,0,sizeof(buff));read(STDIN_FILENO,buff,sizeof(buff));printf("read : %m\n");write(STDOUT_FILENO,buff,sizeof(buff));write(STDOUT_FILENO,"阻塞实验结束\n",sizeof("阻塞实验结束\n"));write(STDOUT_FILENO,"非阻塞实验开始\n",sizeof("非阻塞实验开始\n"));//非阻塞int fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);printf("open : %m\n");printf("fd = %d\n", fd);int i = 0 ;for (i = 0; i < 10; ++i){len = read(fd, buff, sizeof(buff));printf("len = %d\n",len ); if (len < 0) { if (errno == EAGAIN) { sleep(1); // 让出 CPU,避免CPU长时间空转 } else { exit(1); } } else { write(STDOUT_FILENO,buff,sizeof buff); memset(buff,0,sizeof buff); } }close(fd);printf("非阻塞实验结束\n");printf("fcntl实验\n");fd = open(argv[1],O_RDWR|O_APPEND);perror("open");if(fd < 0){exit(0);}int flags = fcntl(fd,F_GETFL);perror("fcntl");if (flags < 0){exit(-1);}if (flags & O_RDONLY) {printf("O_RDONLY\n");}if (flags & O_WRONLY) {printf("O_WRONLY\n");}if (flags & O_RDWR) {printf("O_RDWR\n");}if (flags & O_NONBLOCK) {printf("O_NONBLOCK\n");} return 0;}
- 文件I/O与标准I/O
- 标准I/O、文件I/O
- 文件I/O与标准I/O
- 异步文件 I/O
- 多媒体文件I/O
- 文件I/O
- 文件I/O操作
- 文件I/O操作
- 文件I/O操作
- 文件I/O
- I/O文件库
- 文件I/O
- 文件I/O
- 文件I/O
- 高级文件I/O
- unbuffered 文件I/O
- unix----文件I/O
- 文件I/O
- MYSQL练习2
- 第七周 项目3 负数把正数赶出队列
- 通用块层和SCSI层--硬盘HBA抽象层
- Maven的核心笔记(1)配置Maven环境变量
- String/WString, char* /wchar_t* 相关操作函数
- 文件I/O
- 常见矩阵运算Python
- 第七周 项目6
- 这几个软件你能没听过,但真的每个都好用到爆
- 高并发Java(1):前言
- java设计模式之单例模式
- 捕获未处理的Promise错误
- 神经网络与深度学习学习笔记:神经网络的优化(二)
- 数据结构和算法--常见的排序算法