linux:文件描述符(一)

文件描述符

定义

  • 一个非负整数
  • 应用程序利用文件描述符来访问文件
  • file descriptor,简写为fd

系统调用

  • 打开现存文件或新建文件时,内核会返回一个文件描述符
    读写文件也需要使用文件描述符来指定待读写的文件

打开文件

int open(char *path, int flags, mode_t mode);

内核会返回一个文件描述符fd用来表示该文件
读写时需要使用fd指定待读写的文件

读写文件

int read(int fd, void *buf, size_t size);
int write(int fd, void *buf, size_t size);
  • fd是open返回的文件描述符
  • 用于指定待读写的文件

例子:访问文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int fd;
    fd = open("/etc/hosts", O_RDONLY); 

    char buf[1024];
    int count;
    count = read(fd, buf, sizeof(buf));

    buf[count] = 0;
    puts(buf);

    close(fd);
    return 0;
}

output:

$ ./a.out
127.0.0.1 localhost
$ _

内核实现

简介

内核实现文件描述符的的数据结构

  • 索引节点
  • file结构体
  • 文件描述符表
  • 进程控制块

索引节点

索引节点(inode)是unix文件系统中的一种数据结构
索引节点保存了文件的元信息数据

  • 文件的大小
  • 文件存放在磁盘的位置
  • 文件的创建时间、修改时间
  • 文件的所有者
  • 文件的访问权限

file结构体

内核使用file结构体表示一个被打开的文件
file结构体存了被打开文件的信息

  • 文件对应的索引节点(inode)
  • 文件的当前访问位置
  • 文件的打开模式
  • 只读、只写、可读可写

文件描述符表

  • 文件描述符表是一个数组
  • 数组的元素类型是指针,指针指向一个file结构体
  • 用于保存被打开的文件
  • 内核打开文件时,分配一个file结构体表示被打开的文件,将该file结构体指针保存在文件描述符表中

打开文件的过程

  1. 找到文件对应的索引节点inode
  2. 分配一个file结构体
    file结构体的inode字段指向第1步的inode
    file结构体的文件访问位置字段初始化为0
  3. 从文件描述符表中找一个空闲项
    指向第2步的file结构体
    返回该空闲项在数组中的的下标,即fd

在这里插入图片描述

进程控制块

  • 进程控制块是操作系统表示进程状态的数据结构
  • 存放用于描述进程情况及控制进程运行所需的全部信息
    • 进程标识信息
    • 处理机状态
    • 进程调度信息
    • 打开文件列表,即文件描述符表,记录了该进程打开的文件

私有的文件描述符表

在这里插入图片描述

文件描述符表对进程来说是私有的

  • 每个进程都有一个私有的文件描述符表
  • 操作系统有N个进程,则对应有N张文件描述符表
    两个进程打开不同的文件,文件描述符可能是相同的
  • 进程A打开文件a.txt,open返回值是3
  • 进程B打开文件b.txt,open返回值也可能是3

标准输入输出

简介

在这里插入图片描述

每个进程执行时,会自动打开三个标准文件

  • 标准输入文件,通常对应终端的键盘
  • 标准输出文件,通常对应终端的屏幕
  • 标准错误输出文件,通常对应终端的屏幕
    进程的文件描述符表前三项已经被打开了
  • 第0项,对应标准输入
  • 第1项,对应标准输出
  • 第2项,对应标准错误输出

例子

#include <unistd.h>

int main()
{
    char buf[80];
    int count;

    count = read(0, buf, sizeof(buf));
    buf[count] = 0;
    write(1, buf, count);
}

output:

$ ./a.out
hello
hello
$ _
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值