io学习路线顺序 print–>open–>error–>write–>阻塞–>lseek–>fcntl
~ printf调用操作系统的对外接口,write函数实现输出。—>系统调用
第一个参数文件路径,第二个文件打开方式参数
返回文件描述符
结构体PCB 的成员变量file_struct *file 指向文件描述符表
STDIN_FILENO 0; 标准输入(文件描述符)
STDOUT_FILENO 1;标准输出
STDERR_FILENO 2;错误
int fd = open("./file.txt", O_RDONLY);//返回文件描述符2 表示标准输出到屏幕
close(fd);关闭文件
perror函数: void perror(const char *s);输出错误信息
查看错误号:
/usr/include/asm-generic/errno-base.h
/usr/include/asm-generic/errno.h
if(fd == -1){//打开文件错误
perror("fcntl error");
exit(1);
}
read/write不使用函数库得buffer 一般执行到kernel返回
strace命令
shell中使用strace命令跟踪程序执行,查看调用的系统函数。
while((ret = read(fd, buf, sizeof(buf)))) {//参数一 文件描述符
write(1, buf, ret);//1表示标准输入
}
从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用read从网络读就会阻塞
注意,阻塞与非阻塞是对于文件而言的。而不是read、write等的属性。read终端,默认阻塞读。
read返回值:
#define MSG_TRY "try again\n"
#define MSG_TIMEOUT "time out\n"
if(errno != EAGAIN){ //EWOULDBLK
perror("read /dev/tty");
exit(1);
}
sleep(1);
if(i==5){
write(STDOUT_FILENO, MSG_TIMEOUT, strlen(MSG_TIMEOUT));//5秒后超时
}
write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));//再次尝试
修改文件偏移量(读写位置)
成功:返回的值是较文件起始位置向后的偏移量。
int fseek 成功返回0;失败返回-1
使用lseek拓展文件:write操作才能实质性的拓展文件 单lseek是不能进行拓展
一般:write(fd, “a”, 1);
od -tcx filename 查看文件的16进制表示形式
od -tcd filename 查看文件的10进制表示形式
通过lseek获取文件的大小:lseek(fd, 0, SEEK_END); 【lseek_test.c】
len = lseek(fd, 999, SEEK_SET);//设置大小
int ret = write(fd, "a", 1);//引发拓展
int len = lseek(fd, 0, SEEK_END);//获取大小
通过改变位图控制属性位置的0或者1开进行删除,添加属性
flags = fcntl(STDIN_FILENO, F_GETFL); //获取stdin属性信息
flags |= O_NONBLOCK;//异或添加属性
int ret = fcntl(STDIN_FILENO, F_SETFL, flags);//设置属性
如需转载,请标明此处