在我们日常编程中经常会遇到文件描述符(file descriptor)和文件句柄(file handler)这两个概念,特别是需要开发跨平台(跨windows和linux)项目的时候会被这两个概念搞得很头痛,所以下面来说说它们是什么东西及它们的区别与联系。

文件描述符

本质是一个索引号(非负整数),系统用户层可以根据它找到系统内核层的文件数据。这是一个POSIX标准下的概念,常见于类Unix系统,比如linux。windows也是声称遵循POSIX标准的,所以windows也有文件描述符这个概念,但不常用。

文件句柄

Windows下的概念。句柄是Windows下各种对象的标识符,比如文件(也许叫文档比较合适一点)、资源、菜单、光标、位图等。文件句柄和文件描述符类似,它也是一个非负整数,也用于定位文件数据在内存中的位置。


由于linux下所有东西都被看成是文件,比如文件(也许叫文档比较合适一点)、目录、进程、网络socket、各种硬件设备等,所以linux下的文件描述符其实就相当于windows下的句柄。文件句柄只是windows众多句柄中的一种类型而已。


下面用一张图来说明文件描述符的作用(windows下的句柄也是类似的,只是实现细节不同): 

对上图进行说明之前,还要普及一个知识:一个操作系统对象(比如文件)在内存中的位置是不固定的。它有可能会在虚拟内存和物理内存中来回切换。

  • 由于一个文件在内存中的位置是会变的,而文件管理是系统内核的事,那么对于用户程序来说,要怎么定位它呢?这就是上面那张图要说明的。
  • 这里有三张表:进程文件表,文件概要表和文件节点表。其中进程文件表是每个进程都会有一张,而文件概要表和文件节点表是整个系统各有且只有一张。
  • 文件节点表中每一项数据就是文件的实际数据。
  • 文件概要表中的每一顼是文件的概要数据,它包含了文件的状态、当前文件读写位置、节点指针等。当文件节点表中的数据发生变化时(比如说位置变了),内核会相应地修改文件概要表中对应项的节点指针,让它指向最新的文件数据。
  • 进程文件表里记录了该进程打开的所有文件的文件描述符,看图可以知道文件描述符其实只是一个数组的下标,根据它可以访问数组的数据,而这个数组的数据就是指向该文件对应的文件概要表。
  • 所以,不管文件数据在内存中的哪个位置,只要我们有文件描述符,我们就可以找到该文件的概要数据,从而找到文件的数据来进行操作。

一些补充说明

  • 每个进程创建的时候都会打开三个文件:stdin,stdout和stderr。它们的文件描述符对应为0,1,2。
  • 系统分配文件描述符时总是分配最小可用的值。如果当前进程只使用了0,1,2这三个文件描述符,那下次分配的将是3。如果当前进程只使用了0,1,2,3,5这五个文件描述符,那下次分配的将是4。
  • 不同的文件概要中的节点指针可以指向同一个文件节点,另外,文件描述符与文件概要是一一对应的,因此,不同的文件描述符可以对应相同的文件结点,即同一个文件可以在同一时间内被多次打开,每次打开都会分配一个文件描述符及生成一个文件概要。
  • Windows一般不直接使用文件描述符,所以它提供了一个系统函数叫_get_osfhandle,它可以根据一个文件描述符来获得文件句柄。
  • Windows创建一个文件一定会生成一个文件句柄,但并不一定分配一个文件描述符,如果你需要一个文件描述符,可以使用_open_osfhandle来分配一个。
  • 在windows下不要混用文件描述符与文件句柄,最好就不要用文件描述符了。比如socket这个函数,它在linux下的返回值是一个文件描述符,而在windows下返回的是一个句柄,如果要写跨平台的代码,就得十分小心这些差异。
  • 参考:https://blog.csdn.net/yanjun_1982/article/details/79421528

文件描述符与文件句柄相关推荐

  1. 关于文件句柄数和文件描述符的区分

    在一次生产环境上,用户那边反馈服务连接redis异常,经过查看redis的日志,报打开文件数过多,通过lsof去查看文件句柄数确实超过了主机限制的句柄数,只能先重启redis进行释放连接数,进行恢复业 ...

  2. Linux系统学习笔记:文件描述符标志

    文件描述符标志的概念 文件描述符标志(目前就只有一个close-on-exec): 它仅仅是一个标志,当进程fork一个子进程的时候,在子进程中调用了exec函数时就用到了这个标志.意义是执行exec ...

  3. 文件句柄?文件描述符?傻傻分不清楚

    概述 在实际工作中会经常遇到一些bug,有些就需要用到文件句柄,文件描述符等概念,比如报错: too many open files, 如果你对相关知识一无所知,那么debug起来将会异常痛苦.在li ...

  4. 文件句柄(file handles) 文件描述符(file descriptors)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  5. linux进程文件描述符 vnode,Linux C编程详解:进程原理分析、文件描述符和文件记录表、文件句柄和文件原理...

    一.引言 文件操作是Linux C编程中其中的一项核心技术,实际上也相当重要,这里并不是说狭义上的那种文件操作,它也非常有助于理解和学习Linux系统.为什么这样说呢?因为在Unix/Linux的世界 ...

  6. mysql句柄是文件描述符_误删除innodb ibdata数据文件 文件句柄 文件描述符 proc fd...

    误删除innodb ibdata数据文件  文件句柄  文件描述符  proc  fd http://www.cnblogs.com/gomysql/p/3702216.html 提示:如果不小心通过 ...

  7. linux文件描述符与标识符,文件描述符fd

    这里以问答的方式来讨论这个问题: 1. 文件描述符 fd 和文件指针 FILE *的关系? 文件描述符是什么?我们知道每一个进程都有一个自己的PCB(进程控制块),进程控制块的结构是: struct ...

  8. [转帖]linux文件描述符文件/etc/security/limits.conf

    linux文件描述符文件/etc/security/limits.conf https://blog.csdn.net/fanren224/article/details/79971359 需要多学习 ...

  9. linux 反弹shell(一)文件描述符与重定向

    0X00 前言 由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写 ...

最新文章

  1. SpringMVC 多视图配置
  2. python可以做什么系统-python什么系统
  3. 2019第十届蓝桥杯C/C++ A组省赛 —— 第三题: 最大降雨量
  4. python处理excel文件(xls和xlsx)
  5. android 的各种文件类
  6. Spring Boot Framework的关键组件和内部构造(自动装配、起步依赖、CLI、Actuator)
  7. JS-面向对象-原形对象链(自定义对象实例原形对象链 / 本地对象原形对象链)
  8. 判断点在直线的哪一侧_【倒车入库】车身是否“正直”该怎么判断?
  9. java如何用反射把具体方法抽象_如何在Java 中使用泛型或反射机制对DAO进行抽象...
  10. Netty学习总结(6)——Netty使用注意事项
  11. 计算机二级报名省市,计算机二级报名通知:全国19省市报名时间及考试安排!...
  12. 当电子工程师十余年,感慨万千
  13. 微软拼音输入法调整状态栏水平/垂直选项失效解决办法
  14. 思维导图工具XMind下载
  15. 使用AT89C51芯片实现生日快乐歌
  16. 计算机类高级工程师职称评审
  17. 丰田、雷克萨斯决定在今年将亚马逊Alexa应用到部分车型中
  18. 区块链是什么通俗解释?
  19. 4k超清壁纸APP抓包获取所有壁纸下载地址
  20. [原创]隐身斗篷简介及仿真

热门文章

  1. 你知道1+1=2是如何在cpu中运作的么?----跟我到cpu内部去看看吧!(1)
  2. 考研还是工作?两战失败老道有话说
  3. python修改电脑密码_python修改远程计算机密码
  4. 博士毕业论文致谢句句诛心,博士女朋友回应句句暖心
  5. 【Java面试题1】
  6. 2022世界5G大会值得关注 中兴通讯主题演讲令我印象深刻
  7. CDMP考试难度怎么样?
  8. []转]武侠名字算法
  9. 企业IT技术架构规划方案(资料下载)
  10. Java枚举 根据 key获取value 示例类