Linux文件描述符剖析

文章目录

  • 文件描述符
  • 文件描述符分配规则
  • 重定向
  • 软硬链接
    • 软链接(Symbolic Link):
    • 硬链接(Hard Link):

文件描述符

文件描述符(File Descriptor)是一个非负整数,用于标识打开的文件、套接字或其他I/O资源。它在Unix和类Unix操作系统中是一个重要的概念,用于管理进程对文件和I/O资源的访问。

文件描述符是操作系统内核与用户进程之间通信的一种方式。当用户进程需要访问文件、网络套接字或其他I/O资源时,它通过系统调用(如openreadwriteclose等)向内核请求操作,内核会返回一个文件描述符作为对该资源的引用。进程使用文件描述符来执行读、写、关闭等操作。

每个Unix进程启动时都会自动打开三个标准文件描述符:

  • 0:标准输入(stdin),用于读取输入。
  • 1:标准输出(stdout),用于输出信息。
  • 2:标准错误(stderr),用于输出错误信息。

这些文件描述符在进程启动时就会被分配,它们通常被用来与终端进行交互,但也可以通过重定向来改变它们的行为。

在这里插入图片描述

在Unix和类Unix操作系统中,每个进程都有一个打开文件描述符的表,这个表是通过files_struct结构体来表示的。files_struct结构体中包含了指向打开文件的指针数组,每个元素指向一个打开的文件对象,这些文件对象包含了关于文件的元数据以及指向文件数据的指针等信息。

当进程打开一个文件时,操作系统会在内核中创建一个文件对象(通常是一个file结构体),用来描述该文件的状态和相关信息。然后,操作系统会将这个文件对象添加到进程的文件描述符表中,并将文件描述符返回给进程。这样,进程就可以通过文件描述符来访问相应的文件对象。

因此,文件描述符确实是进程与文件之间的关联,通过文件描述符,进程可以在文件描述符表中找到对应的文件对象,从而对文件进行读取、写入、关闭等操作。

需要注意的是,文件描述符是一个抽象的概念,它并不直接指向文件对象,而是作为索引或标识符,通过它来查找文件对象。在内核中,文件描述符通常被映射到文件对象的数据结构,以便操作系统能够识别和处理相应的文件请求。

文件描述符分配规则

文件描述符通常是从最小的可用非负整数开始分配的。在大多数系统上,前三个文件描述符(0、1、2)通常用于标准输入、标准输出和标准错误,因此新的文件描述符会从3开始分配。

当一个文件描述符被关闭时,操作系统会尽可能快地重新使用该文件描述符。这意味着如果一个文件描述符被关闭,然后另一个文件被打开,那么新的文件描述符很可能会是之前关闭的那个。

  1 #include <stdio.h>2 #include <unistd.h>3 #include <sys/types.h>4 #include <sys/stat.h>5 #include <fcntl.h>6 7 int main()8 {9   printf("%d\n", stdin->_fileno);10   printf("%d\n", stdout->_fileno);11   printf("%d\n", stderr->_fileno);12 13   close(0);                                                                                                                                                                             14   int fd = open("demo.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);15   printf("%d\n", fd);16   return 0;17 }

在这里插入图片描述

总体而言,文件描述符的分配规则通常是简单而直接的,但在编写涉及大量文件处理的程序时,了解文件描述符的分配规则是非常重要的,可以帮助您更好地管理和利用文件描述符资源。

重定向

重定向是Unix和类Unix操作系统中一个重要的概念,它允许将一个命令的输入和输出从默认位置(通常是终端)改变为其他位置,比如文件或另一个进程。

在这里插入图片描述

重定向通过修改文件描述符的行为来实现。具体来说,可以使用以下基本重定向操作符:

  • <:用于将文件内容重定向到命令的标准输入(stdin)。
  • >:用于将命令的标准输出(stdout)重定向到文件中,如果文件不存在,则创建文件;如果文件已存在,则将文件内容截断为零。
  • >>:用于将命令的标准输出(stdout)追加到文件末尾,如果文件不存在,则创建文件。
  1 #include <stdio.h>2 #include <unistd.h>3 #include <sys/types.h>4 #include <sys/stat.h>5 #include <fcntl.h>6 7 int main()8 {9   printf("%d\n", stdin->_fileno);10   printf("%d\n", stdout->_fileno);11   printf("%d\n", stderr->_fileno);12 13   close(1);14   int fd = open("demo.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);15   printf("%d\n", fd);                                                                                                                                                                   16   return 0;17 }

代码中,首先打印了标准输入、标准输出和标准错误的文件描述符0,1,2。然后关闭标准输出文件描述符1后继续的打开文件,这时候就将文件描述符1分配给新打开的文件,所以打印的文件描述符就没有打印到显示器上,而是打印进了文件demo.txt中。

在这里插入图片描述

在Linux系统中,可以使用dupdup2等系统调用来实现文件描述符重定向。这些系统调用允许将一个文件描述符复制到另一个文件描述符,并可以用于将标准输入、标准输出重定向到文件。

  • dup2(oldfd, newfd):将文件描述符oldfd复制到文件描述符newfd上,并关闭newfd之前打开的任何文件。
  • dup(oldfd):复制文件描述符oldfd,返回新的文件描述符。

软硬链接

真正找到磁盘上文件的并不是文件名,而是inode。 其实在linux中可以让多个文件名对应于同一个inode。软链接(Symbolic Link)和硬链接(Hard Link)就是Linux操作系统中用于创建文件链接的两种不同方式。

软链接(Symbolic Link):

  1. 定义: 软链接是一个特殊的文件,它包含了目标文件的路径信息。
  2. 特点:
    • 软链接文件有自己的inode和数据块,它们只是指向目标文件的路径,并不包含实际的数据。
    • 软链接文件的大小为目标文件名的长度加上额外的一些元数据。
    • 软链接可以跨越文件系统边界,可以链接到不同文件系统中的文件。
    • 如果源文件被删除或移动,软链接仍然存在,但它将指向一个无效的位置。
  3. 创建: 使用ln -s命令创建软链接,语法为:ln -s [target] [link_name]

硬链接(Hard Link):

  1. 定义: 硬链接是目标文件的另一个名称,它与原始文件共享相同的inode和数据块。
  2. 特点:
    • 硬链接文件和原始文件具有相同的inode号,因此它们共享相同的数据块。
    • 硬链接不能跨越文件系统边界,只能在同一个文件系统中创建。
    • 如果原始文件被删除,硬链接仍然存在,因为它们共享相同的inode,直到所有链接都被删除。
  3. 创建: 使用ln命令创建硬链接,语法为:ln [target] [link_name]

软链接和硬链接是文件系统中两种不同的链接方式,它们有一些重要的区别:

  1. 指向对象不同:

    • 软链接指向的是文件的路径,而不是文件本身。
    • 硬链接指向的是文件本身的inode,即文件的实际数据块和元数据。
  2. 跨文件系统边界:

    • 软链接可以跨越文件系统边界,即可以链接到不同文件系统中的文件。
    • 硬链接不能跨越文件系统边界,只能在同一个文件系统中创建。
  3. 目标文件删除或移动的影响:

    • 如果软链接指向的目标文件被删除或移动,软链接仍然存在,但是它会变成一个无效的链接。
    • 如果硬链接指向的目标文件被删除,硬链接仍然存在,直到所有指向该文件的硬链接都被删除,才会真正释放文件的数据块和inode。
  4. 文件类型:

    • 软链接是一个特殊类型的文件,它有自己的inode和数据块,但是不包含实际的文件内容。
    • 硬链接是文件本身的另一个名称,它与原始文件共享相同的inode和数据块。
  5. 文件大小:

    • 软链接文件的大小是目标文件路径的长度加上一些额外的元数据大小。
    • 硬链接文件和原始文件共享相同的数据块,因此它们的大小相同。

总的来说,软链接和硬链接各有其自身的特点和应用场景。软链接适用于需要跨越文件系统边界、需要指向目录、或者需要链接到不存在的文件的情况。硬链接适用于需要共享相同数据块的文件,且只能在同一个文件系统中使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/519880.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能控制:物联网智能插座对接文档

介绍 一开始买的某米的插座&#xff0c;但是好像接口不开放&#xff0c;所以找到了这个插座&#xff0c;然后自己开发了下&#xff0c;用接口控制插座开关。wifi的连接方式&#xff0c;通电后一般几秒后就会连接上wifi&#xff0c;这个时候通过接口发送命令给他。 产品图片 通…

C++11线程同步之条件变量

C11线程同步之条件变量 condition_variable成员函数生产者和消费者模型 condition_variable_any成员函数生产者和消费者模型 条件变量是C11提供的另外一种用于 等待的同步机制&#xff0c;它能阻塞一个或多个线程&#xff0c;直到收到另外一个线程发出的通知或者超时时&#x…

ROS 2基础概念#5:执行器(Executor)| ROS 2学习笔记

在ROS 2中&#xff0c;Executor是一个核心概念&#xff0c;负责管理节点&#xff08;Node&#xff09;中的回调函数&#xff0c;如订阅消息的回调、服务请求的回调、定时器回调等。Executor决定了何时以及如何执行这些回调&#xff0c;从而在ROS 2系统中实现异步编程。 ROS 2 …

vscode自定义插件的开发过程记录

前言 本文是关于visual studio code软件上自定义插件的开发记录&#xff0c;将从头记录本人开发的过程&#xff0c;虽然网上也有很多文章&#xff0c;但个人在实践的过程还是会遇到不一样的问题&#xff0c;所以记录下来&#xff0c;以便于后期参考。 前期准备&#xff1a; 1、…

STL之list容器代码详解

1 基础概念 功能&#xff1a; 将数据进行链式存储 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成&#xff1a;链表由一系列结点组成。 结点的组成&#xff1a;一个是存储数…

嵌入式学习第二十五天!(网络的概念、UDP编程)

网络&#xff1a; 可以用来&#xff1a;数据传输、数据共享 1. 网络协议模型&#xff1a; 1. OSI协议模型&#xff1a; 应用层实际收发的数据表示层发送的数据是否加密会话层是否建立会话连接传输层数据传输的方式&#xff08;数据包&#xff0c;流式&#xff09;网络层数据的…

HelpLook VS GitBook:知识库优劣详解

在信息爆炸的时代&#xff0c;企业要保持竞争优势&#xff0c;就必须善于管理和利用内部的知识资产。企业知识库作为一种集中存储和共享知识的工具&#xff0c;正在成为现代企业不可或缺的一部分。 HelpLook和Gitbook是提供专业知识库的两个平台&#xff0c;也被大众熟知。它们…

一文读懂HDMI的演变-从HDMI1.0到HDMI2.1(建议收藏)

HDMI&#xff0c;全称为&#xff08;High Definition Multimedia Interface&#xff09;高清多媒体接口&#xff0c;主要用于传输高清音视频信号。 HDMI System HDMI系统包括HDMI的source和HDMI的sink, 其中source 是源端&#xff0c;即信号的来源&#xff1b;Sink的接收端&a…

什么是以人为本的AI?

AI技术蓬勃发展&#xff0c;有望极大改善我们的日常生活。因此&#xff0c;人工智能专家经常围绕在我们社会中利用人工智能的最佳方式展开对话&#xff0c;并由此得出了以人为中心的AI方法。以人为中心的AI意为不是用机器代替人类&#xff0c;而是用机器来优化人类的体验。 在…

乌鸡的身高

解法&#xff1a; 只需要看身高最高的乌鸡个数是否>2.若满足则除去当前这只乌鸡的最高身高都是最高身高。 若不满足则只需要看最高的和第二高的乌鸡。 #include<iostream> #include<vector> #include<algorithm> #include<cmath> using namespac…

图像检索与识别——词袋模型(Bag-of-features models)

一、定义 计算机视觉单词袋是一种描述计算图像之间相似度的技术&#xff0c;常用于用于图像分类当中。该方法起源于文本检索&#xff08;信息检索&#xff09;&#xff0c;是对NLP“单词袋”算法的扩展。在“单词袋”中&#xff0c;我们扫描整个文档&#xff0c;并保留文档中出…

STL中push_back和emplace_back效率的对比

文章目录 过程对比1.通过构造参数向vector中插入对象&#xff08;emplace_back更高效&#xff09;2.通过插入实例对象&#xff08;调用copy函数&#xff09;3.通过插入临时对象&#xff08;调用move函数&#xff09; 效率对比emplace_back 的缺点 我们以STL中的vector容器为例。…