FileDescriptor(文件描述符 )与Linux文件系统

#### begin 2020-10-17 追加简单类比:

fd是int类型。类比 每个进程有个array,[标注输入文件,标准输出文件、标出错误文件、/sdcard/test.jpg], fd就是进程array的index。

#### end 2020-10-17

 

最近看《Linux System Programming》看到关于fd(File Descriptor)的描述,看java文档感觉似是而非 不太清楚,从linux方面就很容易理解了。

 

简介:

每个进程都有个 映射文件物理地址的表格(0标准输入 1标准输出 2标准错误 3、4、5....就映射你打开过文件的地址),FileDescriptor 相当于这个1、2、3、4.。。。行

每个进程除了0、1、2是相同的,其他的很可能不同。那既然FileDescriptor映射不是一个File,进程间怎么通过FileDescriptor共享文件呢?

1.子进程继承父进程 地址表格的(父进程调用fork 生成子进程)

2.Android Binder机制,A进程mapping文件到进程,再把这个文件的FileDescriptor发给B进程,B进程mapping后操作。都是 Zygote的子进程,他们是不继承地址表的。但是Android做过转化了(怎么转化的就没看了。。。。。)

3. Linux中的Unix Domain Socket(没有网络协议的本地socket)可以IPC(跨进程通信)传递 文件描述符。比如 A进程 unix domain socket给了B进程,当然A进程和B进程的fd的值 可能不同,但指向文件相同。

 

FileDescriptor

一个打开的文件通过唯一的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射。在Linux内核中,这个描述符称为文件描述符(FileDescriptor),文件描述符用一个整数表示(C语言中的类型为int),简写为fd。

文件描述符在用户空间(相对于内核空间而言,也就是我们应用程序的那层)中共享,允许用户程序用文件描述符直接访问文件。

同一个文件能被不同或者相同的进程多次打开,每一个打开文件的实例(也就是java中的File类对象吧)都产生一个唯一的文件描述符。同一个描述符可以被多个进程使用。不同的进程能同时对一个文件进行读写,所以存在并发修改问题。

 

fd如何访问文件

内核为每一个进程维护一个打开文件的列表,称为文件表(File Table),索引是fd,数据为打开文件的信息(包括一个指向文件的Inode对象的指针,和相关元数据,如当前文件文职、读取模式)。(Inode包含文件的物理地址)

简单的讲,也就是有了Map结构,key是fd,value是文件的信息(包括物理地址、读取模式。。。。。)

子进程默认获得一份父进程FIle Table的拷贝,而 更改一个进程的FileTable不会影响另一个进程(如果子进程关闭了文件 不会影响父进程的File Table),所以fd可以用来共享文件。

fd用C语言的int表示非负整数,从0开始递增 直到默认上限1024。按照惯例每个进程至少有三个打开的文件描述符,除非进程显式的关闭他们: 0 标准输入(stdin),1标准输出(stdout),2标准错误(stderr)。

 

Linux中fd打开文件的API

 

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

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);

       int creat(const char *pathname, mode_t mode);

       int openat(int dirfd, const char *pathname, int flags);
       int openat(int dirfd, const char *pathname, int flags, mode_t mode);

 

 

总结

fd的操作实际是系统内核API层次的,java的标准API没有直接相关的操作(据我已知,可以直接通过fd打开文件的)

进程关联一个类似Map的文件表,key是fd,value是文件的物理地址等等信息。

可以通过fd打开文件。

子进程copy父进程的文件表

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值