linux文件描述符,系统打开文件和i节点的关系

首先区分文件描述符和打开的文件

内核维护了三个数据结构
进程级的文件描述符表(即每个进程一个)
系统级的打开文件表(即该表在整个内核中只有一个)
文件系统的 i-node 表
针对每个进程,内核为其维护一个打开的文件描述符表(open file descriptor table),改表的每一项都记录了单个文件描述符的相关信息,如下:
控制文件描述符的操作的一组标识,目前只定义了一个,即 close-on-exec 标识
对打开文件句柄的引用
系统为所有打开的文件维护了一个系统级别的描述表格(open file description table)。该表的每一项保存了一个已打开的文件的所有相关信息,包括如下内容:
文件指针偏移量 (read()和write()修改,以及lseek()修改)
打开文件的状态标识
文件访问模式
与信号驱动I/O相关的设置
指向 i-node 对象的一个指针

这里有两个概念要区分

一个是文件描述符标识,一个是文件标识。显然,文件描述符标识是标识文件描述符的特性,文件标识是标识文件的特性。close-on-exec是文件描述符的标识。O_APPEND 是文件标识。并且文件描述符标识体现在进程文件描述符表结构中。文件状态标识体现在系统打开文件描述符表中。
每个文件系统都有一个i-node结构,包括如下信息:
文件类型和权限,例如regular file,socket等
该文件持有的所有锁
其他各种特性,比如文件大小,时间戳等等

1. 对同一个文件描述符的读和写位置共享。

测试代码:
char buf[128];
int main(int argc,char *argv[])
{
        char *s = "test";
        int fd = open("test.txt",O_RDWR);
        if(fd == -1)
        {
                perror("open test.txt failure");
                exit(EXIT_FAILURE);
        }

        int readNum = read(fd,buf,3);
        write(fd,s,4);
        if(-1 == close(fd))
        {
                perror("close failure");
                exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
}
测试条件,test.txt文件的初始内容为123456789
测试结果:程序执行之后test.txt文件的内容为123test89
分析:
1. 对 test.txt 进行了读写打开
2. 先对test.txt 读3个字节,所以此时fd的偏移量应该是3
3. 接着对fd写4个字节,根据最终的输出结果可以知道此时是从偏移量为3的地方开始写的,所以对于同一个文件描述符来说,读写位置是共享的。

2. 同一个进程多次打开同一个文件

测试代码:
int main(int argc,char *argv[])
{
        char buf[10];
        char *s = "test";
        int fd1 = open("test.txt",O_RDWR);

        int readNum = read(fd1,buf,3);


        int fd2 = open("test.txt",O_RDWR);
        write(fd2,s,4);
}
测试条件,test.txt文件的初始内容为123456789
测试结果:程序执行之后test.txt文件的内容为test56789
分析:
1. 对 test.txt 进行了第一次open操作得到fd1
2. 先通过fd1对test.txt 读3个字节,所以此时fd1所对应的偏移量应该是3
3. 接着对test.txt进行了第二次open操作,得到了fd2,
4. 通过fd2对test.txxt写4个字节,根据最终的输出结果可以知道此时是从偏移量为0的地方开始写的
5. 综上所述,如果对同一个文件打开多次,那么这些文件描述符所对应的内核结构是独立的。
6、从上面的结果也可以看出来,即使是同一个文件,如果我们打开了多次,那么内核也会维护多个打开文件表项。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值