在Linux系统中,“一切皆文件”(Everything is a file)是一个核心设计哲学,它抽象了系统资源的访问方式,使得几乎所有硬件设备、进程、网络连接等都可以通过统一的文件接口(如open()read()write()close()等系统调用)进行操作。

目录

一、在Linux系统中,"文件"的概念比Windows更为广泛

二、Linux中的文件

1、普通文件(Regular Files)

2、目录(Directories)

3、设备文件(Device Files)

4、命名管道(Named Pipes, FIFO)

5、套接字(Sockets)

6、符号链接(Symbolic Links)

7、伪文件系统(ProcFS, SysFS, etc.)

8、标准输入/输出/错误(stdin, stdout, stderr)

9、例外情况

三、这一设计的主要优势在于

为什么这样设计?

四、补充说明


一、在Linux系统中,"文件"的概念比Windows更为广泛

  1. Windows中的文件在Linux中同样被视为文件
  2. Windows中非文件对象(如进程、磁盘、显示器、键盘等硬件设备)在Linux中也被抽象为文件
  3. 管道同样被视为文件
  4. 后续将学习到的网络编程中的套接字(socket)也采用文件接口

二、Linux中的文件

1、普通文件(Regular Files)

  • 包括文本文件、二进制文件等,存储在磁盘或其他存储设备中。

  • 例如:/home/user/document.txt

2、目录(Directories)

  • 目录本质上是包含其他文件列表的特殊文件。

  • 例如:/etc/ 目录中保存了系统配置文件列表。

3、设备文件(Device Files)

Linux将硬件设备抽象为文件,分为两类:

  • 块设备(Block Devices):以固定大小的数据块访问(如磁盘)。

    • 例如:/dev/sda(第一块硬盘)。

  • 字符设备(Character Devices):以字符流形式访问(如键盘、鼠标)。

    • 例如:/dev/tty(终端设备)。

示例操作:

# 向磁盘设备写入数据(需谨慎!)
dd if=file.img of=/dev/sdb# 从鼠标设备读取输入(需权限)
cat /dev/input/mouse0

4、命名管道(Named Pipes, FIFO)

  • 用于进程间通信(IPC)的特殊文件,数据先进先出。

  • 示例:

    mkfifo /tmp/my_pipe
    echo "Hello" > /tmp/my_pipe &  # 写入端
    cat < /tmp/my_pipe            # 读取端

5、套接字(Sockets)

  • 用于网络或本地进程间通信的文件。

  • 例如:/var/run/docker.sock 是Docker守护进程的通信套接字。

6、符号链接(Symbolic Links)

  • 指向其他文件的快捷方式。

  • 例如:/bin/sh 可能是指向 /bin/bash 的符号链接。

7、伪文件系统(ProcFS, SysFS, etc.)

  • /proc:动态反映进程和内核状态的文件(如/proc/cpuinfo/proc/1234/为PID 1234的进程信息)。

  • /sys:暴露内核设备和驱动的配置(如调节CPU频率)。

示例:

# 查看CPU信息
cat /proc/cpuinfo# 修改系统参数(如最大进程数)
echo 10000 > /proc/sys/kernel/pid_max

8、标准输入/输出/错误(stdin, stdout, stderr)

  • 在Linux中,这些标准流也通过文件描述符访问:

    • 0:stdin(如键盘输入)。

    • 1:stdout(如终端输出)。

    • 2:stderr(如错误输出)。

重定向示例:

ls /nonexistent 2> /dev/null  # 将错误输出重定向到“黑洞”设备

9、例外情况

并非所有资源都是文件,例如:

  • 线程调度、内存分配等底层操作仍需通过系统调用(如mmap())。

  • 某些现代内核特性(如cgroups)可能不完全遵循此规则。


、这一设计的主要优势在于

  • 开发者仅需掌握一套API和开发工具即可调用系统大部分资源
  • 几乎所有读取操作(读取文件、系统状态、管道等)都可通过read函数实现
  • 几乎所有写入操作(修改文件、系统参数、管道等)都可通过write函数完成

为什么这样设计?

  • 统一性:所有资源通过文件接口操作,简化编程模型。

  • 抽象性:用户无需关心底层细节(如硬件差异)。

  • 灵活性:文件权限(如chmod)、重定向(如>)等机制可通用。


四、补充说明

        当打开文件时,系统会创建对应的file结构体进行管理。该结构体定义于: /usr/src/kernels/3.10.0-1160.71.1.el7.x86_64/include/linux/fs.h 以下展示该结构体的相关部分内容:

struct file {...struct inode *f_inode;     /* Cached inode pointer */const struct file_operations *f_op;...atomic_long_t f_count;     /* Reference count for open files */unsigned int f_flags;      /* File access flags (read/write permissions) */fmode_t f_mode;            /* File access mode (defined in headers) */loff_t f_pos;              /* Current read/write position */...
} __attribute__((aligned(4))); /* Force 4-byte alignment */

        值得注意的是,struct file 中的 f_op 指针指向一个 file_operations 结构体,该结构体除 struct module* owner 成员外,其余均为函数指针。这两个结构体均定义于 fs.h 头文件中:

struct file_operations {struct module *owner;           // 指向所属模块的指针loff_t (*llseek)(struct file *, loff_t, int);  // 修改文件当前读写位置,返回新位置ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);  // 从设备读取数据,NULL返回-EINVALssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);  // 向设备写入数据,NULL返回-EINVALssize_t (*aio_read)(struct kiocb *, const struct iovec *, unsigned long, loff_t);  // 初始化异步读操作ssize_t (*aio_write)(struct kiocb *, const struct iovec *, unsigned long, loff_t);  // 初始化异步写操作int (*readdir)(struct file *, void *, filldir_t);  // 仅对文件系统有用,设备文件应为NULLunsigned int (*poll)(struct file *, struct poll_table_struct *);  // 轮询设备状态int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);  // 设备控制接口long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);  // 无锁版ioctllong (*compat_ioctl)(struct file *, unsigned int, unsigned long);  // 兼容版ioctlint (*mmap)(struct file *, struct vm_area_struct *);  // 将设备内存映射到进程地址空间,NULL返回-ENODEVint (*open)(struct inode *, struct file *);  // 打开文件int (*flush)(struct file *, fl_owner_t id);  // 进程关闭文件描述符时调用int (*release)(struct inode *, struct file *);  // 文件结构释放时调用int (*fsync)(struct file *, struct dentry *, int datasync);  // 刷新挂起数据int (*aio_fsync)(struct kiocb *, int datasync);  // 异步刷新int (*fasync)(int, struct file *, int);  // 异步通知int (*lock)(struct file *, int, struct file_lock *);  // 文件锁定(设备驱动很少实现)ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);  // 发送页面unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);  // 获取未映射区域int (*check_flags)(int);  // 检查标志int (*flock)(struct file *, int, struct file_lock *);  // 文件锁定ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);  // 管道写入ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);  // 管道读取int (*setlease)(struct file *, long, struct file_lock **);  // 设置租约
};

    file_operation 是连接系统调用与驱动程序的核心数据结构,其每个成员都对应着一个特定的系统调用。当系统调用执行时,会读取 file_operation 中对应的函数指针,并将控制权转交给该函数,从而完成 Linux 设备驱动程序的调用流程。

为帮助理解,我们用一张图来总结上述内容:

        图中的外设设备虽然各自拥有独立的读写操作方式,但通过 struct file 结构中 file_operation 的函数回调机制,开发者仅需使用 file 接口就能访问 Linux 系统中的绝大多数资源。这正是"Linux下一切皆文件"理念的核心体现。

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

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

相关文章

蓝桥杯零基础到获奖-第3章 C++ 变量和常量

蓝桥杯零基础到获奖-第3章 C 变量和常量 文章目录一、变量和常量1.变量的创建2.变量初始化3.变量的分类4.常量4.1 字⾯常量4.2 #define定义常量4.3 const 定义常量4.4 练习练习1&#xff1a;买票https://www.nowcoder.com/practice/0ad8f1c0d7b84c6d8c560298f91d5e66练习2&…

物理AI是什么技术?

当英伟达CEO黄仁勋在链博会上明确提出“物理AI将是AI的下一浪潮”时&#xff0c;这个看似陌生的概念瞬间引发了科技圈的广泛关注。究竟什么是物理AI&#xff1f;它与我们熟悉的人工智能有何不同&#xff1f;又将如何重塑我们与物理世界的交互方式&#xff1f; 物理AI&#xff1…

GRIB数据处理相关指令

GRIB 数据格式简介 GRIB(General Regularly distributed Information in Binary form)&#xff0c;是由世界气象组织&#xff08;WMO&#xff09;设计和维护的一种用于存储和传输网格数据的标准数据格式&#xff0c;它是一种自描述的二进制压缩格式&#xff0c;通常具有扩展名…

微服务学习(六)之分布式事务

微服务学习&#xff08;六&#xff09;之分布式事务一、认识Seata二、部署TC服务1、准备数据库表2、准备配置文件3、docker部署三、微服务集成seata1、引入依赖2、改造配置3、添加数据库表4、测试四、XA模式1、两阶段提交2、seata的XA模型3、优缺点4、实现步骤五、AT模式1、Sea…

Go实现用户登录小程序

写一个用户登录注册的小程序 运行程序&#xff0c;给出提示1. 注册输入用户名、密码、年龄、性别 {"用户名": "root", "passwd": "123456", "age": 18, "sex": "男"}注册前要判断是否存在此用户2. 登录…

鸿蒙蓝牙通信

https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-bluetooth-low-energy 蓝牙权限 module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.ACCESS_BLUETOOTH","reason": "…

Java:Map

文章目录Map常用方法Map遍历的三种方法先获取Map集合的全部键&#xff0c;再通过遍历来找值Entry对象forEach结合lambda表达式Map 案例分析需求我的代码&#xff08;不好&#xff09;老师的代码&#xff08;好&#xff09;好在哪里另外集合分为Collection和MapMap常用方法 代码…

fastjson2 下划线字段转驼峰对象

在对接第三方或查询数据库时&#xff0c;返回的字段是下划线分隔的&#xff0c;而在业务中需要转成java对象&#xff0c;java对象的字段是驼峰的&#xff0c;使用fastjson2时&#xff0c;有两种方法可以实现&#xff1a; 比如数据格式是&#xff1a; {"item_id": &q…

【硬件】蓝牙音频协议

1. 无线音频传输的工作原理 在无线传输的过程中&#xff0c;音源设备首先将MP3、FLAC等音频文件还原为PCM格式。通过蓝牙音频编码转为蓝牙无线传输的文件&#xff0c;发送到音频设备段。将蓝牙无线传输的文件再次还原为PCM格式&#xff0c;之后转为模拟信号并放大&#xff0c;通…

【宇树科技:未来1-3年,机器人可流水线打螺丝】

在第三届中国国际供应链促进博览会上&#xff0c;宇树科技工作人员表示&#xff0c;未来1到3年内&#xff0c;机器人产品有望从单一工业化产品&#xff0c;发展至复合化工业场景&#xff0c;如机器人搬完箱子后&#xff0c;换个 “手” 就能在流水线上打螺丝。在3到10年内&…

Spring AI 1.0版本 + 千问大模型之 文本记忆对话

上篇文章&#xff0c;主要是简单讲解了一下文本对话的功能。由于模型不具备上下文记忆功能&#xff0c;只能一问一答。因此我们需要实现记忆对话功能&#xff0c;这样大模型回答信息才能够更加准确。 1、pom依赖 项目构建就不详细说了&#xff0c;大家可以参考上篇 文本对话 文…

测试学习之——Pytest Day2

一、Pytest配置框架Pytest的配置旨在改变其默认行为&#xff0c;以适应不同的测试需求和项目结构。理解其配置层级和常用参数&#xff0c;是高效使用Pytest的基础。1. 配置的意义与层级配置的本质在于提供一种机制&#xff0c;允许用户根据项目特点、团队规范或特定测试场景&am…

Go-Redis × RediSearch 全流程实践

1. 连接 Redis ctx : context.Background()rdb : redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "",DB: 0,Protocol: 2, // 推荐 RESP2// UnstableResp3: true, // 若要体验 RESP3 Raw* })2. 准备示例数据 u…

深入理解指针(指针篇2)

在指针篇1我们已经了解了整型指针&#xff0c;当然还有很多其他类型的指针&#xff0c;像字符指针、数组指针、函数指针等&#xff0c;他们都有他们的特别之处&#xff0c;让我们接着学习。1. 指针类型介绍和应用1.1 字符指针变量字符指针变量类型为char*&#xff0c;一般这样使…

Python+Selenium自动化爬取携程动态加载游记

1. 引言 在旅游行业数据分析、舆情监测或竞品研究中&#xff0c;获取携程等平台的游记数据具有重要价值。然而&#xff0c;携程的游记页面通常采用动态加载&#xff08;Ajax、JavaScript渲染&#xff09;&#xff0c;传统的**<font style"color:rgb(64, 64, 64);backg…

ESP8266服务器建立TCP连接失败AT+CIPSTART=“TCP“,“192.168.124.1“,8080 ERROR CLOSED

1.检查服务器端口8081是否开启监听2.检查路由项是否被防火墙拦截方法 1&#xff1a;使用 netsh查看防火墙规则​netsh advfirewall firewall show rule nameall dirout | findstr "8081"如果无输出&#xff0c;说明防火墙未针对该端口设置规则&#xff08;可能默认拦…

Linux 内存管理(2):了解内存回收机制

目录一、透明大页1.1 原理1.2 透明大页的三大优势1.3 透明大页控制接口详解1.4 使用场景与最佳实践1.5 问题排查与监控1.6 与传统大页的对比二、Linux伙伴系统水位机制详解2.1 三种核心水位详解2.2 水位在伙伴系统中的实现2.3 水位触发机制的实际行为2.4 水位关键操作接口2.5 水…

前端学习7:CSS过渡与动画--补间动画 (Transition) vs 关键帧动画 (Animation)

一、补间动画&#xff08;Tween Animation&#xff09;vs 关键帧动画&#xff08;Keyframe Animation&#xff09;概念对比表&#xff1a;补间动画 (Transition)关键帧动画 (Animation)定义元素从初始状态到结束状态的过渡效果通过定义多个关键帧控制动画的中间状态触发方式需要…

PyTorch 损失函数详解:从理论到实践

目录 一、损失函数的基本概念 二、常用损失函数及实现 1. 均方误差损失&#xff08;MSELoss&#xff09; 2. 平均绝对误差损失&#xff08;L1Loss/MAELoss&#xff09; 3. 交叉熵损失&#xff08;CrossEntropyLoss&#xff09; 4. 二元交叉熵损失&#xff08;BCELoss&…

MinIO深度解析:从核心特性到Spring Boot实战集成

在当今数据爆炸的时代&#xff0c;海量非结构化数据的存储与管理成为企业级应用的关键挑战。传统文件系统在TB级数据面前捉襟见肘&#xff0c;而昂贵的云存储服务又让中小企业望而却步。MinIO作为一款开源高性能对象存储解决方案&#xff0c;正以其独特的技术优势成为开发者的首…