3.文件IO

文件表

进程控制块(PCB): 用来描述进程信息和相关资源,使用一个struct来描述
在这个struct中存在一个数组成员struct file* filp[NR_OPEN)
struct file结构如下:

struct file {
	unsigned short f_mode;// 文件权限
	unsigned short f_flags;// 文件状态
	unsigned short f_count;// 引用计数
	struct m_inode* f_inode;// 文件在磁盘上的位置信息
	off_t f_pos;// 偏移量
}

filp数组的索引即为文件描述符,对用的元素为一个struct file类型的文件表指针
f_count: 当f_count == 0时,才真正关闭文件
dup2函数可以让两个不同的描述符指向同一个文件表

int dup2(int oldfd, int newfd) {
	// ...
	close(newfd);
	filp[newfd] = filp[oldfd];
	filp[newfd]->count++;
	// ...
	return 0;
}

dup函数只接受一个oldfd参数,返回值为新分配的描述符
f_pos: 文件偏移量
lseek函数修改文件偏移量f_pos

off_t lseek(int fd, off_t offset, int whence);

改变filp[fd]指向的文件表struct file结构体中f_pos成员.
open函数打开的文件f_pos默认为0.
whence 表示基准值,offset 表示偏移大小

  • whence 等于SEEK_SET,起始位置,f_pos = 0 + offset
  • whence 等于SEEK_CUR,当前位置,f_pos = f_pos + offset
  • whence 等于SEEK_WHENCE,文件末尾,f_pos = 文件长度 + offset

非阻塞IO

以非阻塞方式打开一个文件

int fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);

非阻塞read,如果没有数据到来,返回-1.
此时需要通过全局变量errno来判断是出错还是没有数据可读,如果errno为E_WOULDBLOCK或E_AGAIN,表示当前没有数据可读.

使用fcntl函数设置文件非阻塞标志

int fcntl(int fd, int cmd = F_GETFL); // 获取文件标志位
int fcntl(int fd, int cmd = F_SETFL, int arg); // 设置文件标志位
int fd = open("/dev/tty", O_RDWR);
int flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);

猜你喜欢

转载自blog.csdn.net/u012086173/article/details/86435120
3.