在平时的 Android 开发中,你与文件描述符打过交道吗?一些知识点会涉及到文件描述符,比如:
mmap 函数的文件描述符参数
epoll 机制对文件描述符的限制
这时,如果让你说说对文件描述符的了解,你能回答上来吗?
不了解也没关系,集中注意力,我们一起来搞定它!
基础概念
Linux 中一切都可以看作文件,包括普通文件、链接文件、Socket 以及设备驱动等,对其进行相关操作时,都可能会创建对应的文件描述符。
文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,用于指代被打开的文件,对文件所有 I/O 操作相关的系统调用都需要通过文件描述符。
与文件的关系
下图为 Linux 系统中的三种表:
进程级别的文件描述符表:内核为每个进程维护一个文件描述符表,该表记录了文件描述符的相关信息,包括文件描述符、指向打开文件表中记录的指针。
系统级别的打开文件表:内核对所有打开文件维护了一个进程共享的打开文件描述表,表中存储了处于打开状态文件的相关信息,包括文件类型、访问权限、文件操作函数(file_operations)等。
系统级别的 i-node 表:i-node 结构体记录了文件相关的信息,包括文件长度,文件所在设备,文件物理位置,创建、修改和更新时间等,"ls -i" 命令可以查看文件 i-node 节点
查看文件描述符资源
文件描述符是一种系统资源,可以通过以下命令来查看文件描述符的上限:
|
|
也可以查看某进程当前已使用的 fd :
|
|
上图中是一个 Android 应用进程,所以能看到 ashmem、binder 等 Android 特有设备文件相关的 fd 。
文件描述符的上限
来看一个实际打开磁盘文件的例子:
|
|
执行上面代码后会申请一个对应的 fd:
|
|
实际开发中,可能会遇到 fd 资源超过上限导致的 "Too many open files" 之类的问题,一般都是因为没有及时释放掉 fd,比如上面代码中 FileOutputStream 没有关闭,若循环执行超过单个进程允许打开的最大 fd 数量,程序就会出现异常。
END
推荐阅读
关注我
助你升职加薪
Android 面试官
点亮在看,年薪百万!