01 文件I/O

io学习路线顺序 print–>open–>error–>write–>阻塞–>lseek–>fcntl

print函数调用

~ printf调用操作系统的对外接口,write函数实现输出。—>系统调用
01 文件I/O_第1张图片

open/close 函数

第一个参数文件路径,第二个文件打开方式参数
返回文件描述符
结构体PCB 的成员变量file_struct *file 指向文件描述符表
STDIN_FILENO 0; 标准输入(文件描述符)
STDOUT_FILENO 1;标准输出
STDERR_FILENO 2;错误

 

int fd = open("./file.txt", O_RDONLY);//返回文件描述符2 表示标准输出到屏幕
close(fd);关闭文件

01 文件I/O_第2张图片

错误函数

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函数

read/write不使用函数库得buffer 一般执行到kernel返回
strace命令
shell中使用strace命令跟踪程序执行,查看调用的系统函数。

while((ret = read(fd, buf, sizeof(buf)))) {//参数一 文件描述符
        write(1, buf, ret);//1表示标准输入
    }

01 文件I/O_第3张图片

阻塞、非阻塞

从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用read从网络读就会阻塞

注意,阻塞与非阻塞是对于文件而言的。而不是read、write等的属性。read终端,默认阻塞读。
read返回值:

  1. 返回非零值: 实际read到的字节数
  2. 返回-1: 1):errno != EAGAIN (或!= EWOULDBLOCK) read出错
    2):errno EAGAIN ( EWOULDBLOCK) 设置了非阻塞读,并且没 有数据到达。
  3. 返回0:读到文件末尾
#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));//再次尝试

lseek函数

修改文件偏移量(读写位置)
成功:返回的值是较文件起始位置向后的偏移量。
int fseek 成功返回0;失败返回-1

  1. 使用lseek拓展文件:write操作才能实质性的拓展文件 单lseek是不能进行拓展
    一般:write(fd, “a”, 1);
    od -tcx filename 查看文件的16进制表示形式
    od -tcd filename 查看文件的10进制表示形式

  2. 通过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);//获取大小

fcntl函数

通过改变位图控制属性位置的0或者1开进行删除,添加属性

flags = fcntl(STDIN_FILENO, F_GETFL); //获取stdin属性信息
flags |= O_NONBLOCK;//异或添加属性
int ret = fcntl(STDIN_FILENO, F_SETFL, flags);//设置属性

01 文件I/O_第4张图片

如需转载,请标明此处

你可能感兴趣的:(linux系统基础)