Linux文件描述符和打开文件之间的关系

简介: 文件描述符和打开的文件之间似乎呈现出一一对应的关系。然而,实际并非如此。多个文件描述符指向同一打开文件,这既有可能,也属必要。这些文件描述符可在相同或不同的进程中打开。要理解具体情况如何,需要查看由内核维护的 3 个数据结构。进程级的文件描述符表。系统级的打开文件表。文件系统的 i-node 表。上述讨论揭示出如下要点。两个不同的文件描述符,若指向同一打开文件句柄,将共享同一文件偏移量。

简介

文件描述符和打开的文件之间似乎呈现出一一对应的关系。然而,实际并非如此。多个文件描述符指向同一打开文件,这既有可能,也属必要。这些文件描述符可在相同或不同的进程中打开。

要理解具体情况如何,需要查看由内核维护的 3 个数据结构。

  • 进程级的文件描述符表。
  • 系统级的打开文件表。
  • 文件系统的 i-node 表。

1.进程级的文件描述符表。

针对每个进程,内核为其维护打开文件的描述符表。该表的每一条目都记录了单个文件描述符的相关信息,如下所示。

  • 控制文件描述符操作的一组标志。
  • 对打开文件句柄的引用。

2.系统级的打开文件表。

内核对所有打开的文件维护有一个系统级的描述表格。有时,也称之为打开文件表,并将表中各条目称为打开文件句柄。一个打开文件句柄存储了与一个打开文件相关的全部信息,如下所示。

  • 当前文件偏移量(调用 read()和 write()时更新,或使用 lseek()直接修改)。
  • 打开文件时所使用的状态标志(即,open()的 flags 参数)。
  • 文件访问模式(如调用 open()时所设置的只读模式、只写模式或读写模式)。
  • 与信号驱动 I/O 相关的设置
  • 对该文件 i-node 对象的引用。

3.文件系统的 i-node 表。

每个文件系统都会为驻留其上的所有文件建立一个 i-node 表。第 14 章将详细讨论 i-node 结构和文件系统的总体结构。这里只是列出每个文件的 i-node 信息,具体如下。

  • 文件类型(例如,常规文件、套接字或 FIFO)和访问权限。
  • 一个指针,指向该文件所持有的锁的列表。
  • 文件的各种属性,包括文件大小以及与不同类型操作相关的时间戳。

此处将忽略 i-node 在磁盘和内存中的表示差异。磁盘上的 i-node 记录了文件的固有属性,诸如:文件类型、访问权限和时间戳。访问一个文件时,会在内存中为 i-node 创建一个副本,其中记录了引用该 i-node 的打开文件句柄数量以及该 i-node 所在设备的主、从设备号,还包括一些打开文件时与文件相关的临时属性,例如:文件锁。

图文细嗦

image-20231024210621670

​ 上图展示了文件描述符、打开的文件句柄以及 i-node 之间的关系。在下图中,两个进程拥有诸多打开的文件描述符。

在进程 A 中,文件描述符 1 和 20 都指向同一个打开的文件句柄(标号为 23)。这可能是通过调用 dup()、dup2()或 fcntl()而形成的

​ 进程A的文件描述符2和进程B的文件描述符2都指向同一个打开的文件句柄(标号为73)。这种情形可能在调用 fork()后出现(即,进程 A 与进程 B 之间是父子关系),或者当某进程通过UNIX 域套接字将一个打开的文件描述符传递给另一进程时,也会发生

​ 此外,进程 A 的描述符 0 和进程 B 的描述符 3 分别指向不同的打开文件句柄,但这些句柄均指向 i-node 表中的相同条目(1976),换言之,指向同一文件。发生这种情况是因为每个进程各自对同一文件发起了 open()调用。同一个进程两次打开同一文件,也会发生类似情况。

总结

上述讨论揭示出如下要点。

  • 两个不同的文件描述符,若指向同一打开文件句柄,将共享同一文件偏移量。因此,如果通过其中一个文件描述符来修改文件偏移量(由调用 read()、write()或 lseek() 所致),那么从另一文件描述符中也会观察到这一变化。无论这两个文件描述符分属于不同进程,还是同属于一个进程,情况都是如此。
  • 要获取和修改打开的文件标志(例如,O_APPEND、O_NONBLOCK 和 O_ASYNC),可执行 fcntl()的 F_GETFL 和 F_SETFL 操作,其对作用域的约束与上一条颇为类似。
  • 相形之下,文件描述符标志(亦即,close-on-exec 标志)为进程和文件描述符所私有。对这一标志的修改将不会影响同一进程或不同进程中的其他文件描述符。
目录
相关文章
|
18天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
39 5
|
18天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
36 6
|
18天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
53 6
|
19天前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
34 4
|
25天前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
46 2
|
24天前
|
缓存 监控 Linux
|
27天前
|
Linux Shell 数据库
文件查找是Linux用户日常工作的重要技能介绍了几种不常见的文件查找方法
文件查找是Linux用户日常工作的重要技能。本文介绍了几种不常见的文件查找方法,包括使用`find`和`column`组合、`locate`和`mlocate`快速查找、编写Shell脚本、使用现代工具`fd`、结合`grep`搜索文件内容,以及图形界面工具如`Gnome Search Tool`和`Albert`。这些方法能显著提升文件查找的效率和准确性。
43 2
|
1月前
|
Linux 数据库
linux 全局搜索文件
在 Linux 系统中,全局搜索文件常用 `find`、`locate` 和 `grep` 命令。`find` 根据文件名、类型、大小、时间戳等条件搜索;`locate` 通过预构建的数据库快速查找文件;`grep` 在文件中搜索特定文本,常与 `find` 结合使用。选择合适的命令取决于具体需求。
|
2月前
|
Linux 开发工具 Perl
Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
【10月更文挑战第20天】Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
42 4
|
2月前
|
运维 安全 Linux
Linux文件清空的五种方法总结分享
每种方法各有优势,选择最合适的一种或几种,可以极大提高您的工作效率。更多有关Linux系统管理的技巧与资源,欢迎访问,持续提升您的运维技能。
76 1