[Linux]基础IO

news2025/4/1 23:33:47

基础IO

  • C文件IO相关操作
  • 磁盘文件与内存文件
  • inode(index node)
  • 硬链接与软连接
    • 硬链接
    • 软连接
    • 总结
  • 动静态库
    • 静态库
    • 动态库
    • 总结

C文件IO相关操作

当前路径:进程运行的时候,所处的路径叫做当前路径

打开文件的时候,一定是进程运行的时候才打开的
在Linux中,一切皆是文件(显示器、键盘也是文件)

printf 打印 -> 写入到显示器文件中

任何进程在运行的时候,都会默认打开3个输入输出流:
stdin(标准输入流):键盘——0
这是程序默认接收输入的流,通常指从键盘输入的数据。程序从这个流中读取数据。你可以通过键盘输入字符或命令,程序会通过标准输入流获取这些信息。

stdout(标准输出流):显示器——1
这是程序默认输出结果的流,通常是输出到显示器上的文本。例如,你在屏幕上看到的打印信息或输出的结果,都是通过标准输出流传递的。

stderr(标准错误流):显示器——2
这是程序用来输出错误信息的流。不同于标准输出流,标准错误流专门用于显示程序错误、警告或其他异常情况的消息。虽然默认也输出到显示器,但stderr的输出通常被独立处理,以便于错误信息和正常输出分开管理。

在计算机中,流(stream)是一种用于在程序中处理输入和输出(I/O)数据的抽象概念。流可以是数据传输的通道,通过它,程序可以与外部世界进行交互。流的类型主要有两种:输入流(input stream)和输出流(output stream)。

在这里插入图片描述
在这里插入图片描述

系统函数参数传参标志位:int、32bit、理论上可以传递32种标志位

例如:

二进制序列中只有1bit是1
#define X 0x1
#define Y 0x2
#define Z 0x4

open(arg1, arg2 = X | Y , arg3) // 通过按位或 | 合并多个标志,生成一个整数值
{
    // 若 arg2 包含 X,则 arg2 & X 结果为非零(条件为真)
	if(arg2 & X)
	{}
	if(arg2 & Y)
	{}
}	
可以用bit位在参数中传送多个选项
这些宏特点是只有一个二进制位为1
int fd = open("log.txt", 0_WRONLY | 0_CREAT, 0666); // 一次可以传递2个标志位 用 | 的方式

关闭文件:

#include <unistd.h>

close(fd);

一个进程可以打开多个文件吗?——可以

系统中,任意时刻,都可能存在大量的已经打开的文件(打开的文件——文件管理——先描述在组织 )

磁盘文件与内存文件

1、磁盘文件(持久化存储层面)

磁盘文件是存储在硬盘(或者其他持久化存储介质)上的文件。

文件系统会为其维护文件名、文件内容、以及各种元信息(metadata),如大小、权限、创建/修改时间、所有者等。

当进程想要访问某个文件时,需要通过系统调用(如 open())让操作系统内核去查找磁盘上的该文件,并为进程创建相应的内核数据结构(如 struct file)来管理打开的文件。
磁盘文件:文件 = 内容 + 属性(即元信息,如修改日期 类型 等)

2、内存文件(进程打开后的内核层面)

当进程打开一个文件后,在内核中会分配一个与该文件对应的内存数据结构(通常是 struct file 或者跟它相关的结构体,比如 file、inode、dentry 等),也可以把它理解成“内存文件”或“打开文件的内存表示”。

这些数据结构包含了:

文件指针(文件偏移量,即当前读写的位置)。

指向文件元信息的指针(如 inode、dentry,里面包含文件在磁盘上的各种信息)。

缓冲区/缓存相关信息:操作系统会对文件进行缓存(page cache / buffer cache),以便加速读写。

引用计数等其他管理信息(比如有多少进程共享打开这个文件描述符)。

因为每个进程都可能打开多个文件,所以操作系统会限制单个进程能打开的最大文件描述符数。这个限制可以通过系统参数(如 ulimit -n)进行修改。

3、「内存文件」和「磁盘文件」的区别与联系

a)持久化 vs 临时性

磁盘文件是持久化的,保存在文件系统中,不会因为进程退出而消失(除非显式删除)。

内存文件(打开时对应的 struct file 等)只是进程运行时的状态,进程退出或关闭文件后,这些结构就被内核释放了。

b)内容与属性

磁盘文件不仅有真正的文件内容,还在文件系统中保存着各种元信息(权限、时间戳、所有者等)。

内存文件则是内核为该文件创建的管理结构,里面记录了当前读写位置、引用计数、缓存信息等,更多是“状态”和“指针”,本身并不真正存储文件的所有内容(实际内容还在内核的缓存区或者磁盘中)。

c)打开/关闭文件的过程

当用户通过 open() 打开一个磁盘文件时,内核会做以下工作:

找到文件系统中的对应文件(磁盘文件)。

创建/获取对应的 inode、dentry 等对象。

为该文件创建或复用 struct file 结构,并初始化读写偏移、权限检查、缓存等信息。

返回一个文件描述符(fd)给用户进程。

关闭文件时(如 close(fd)),内核会相应地更新内存数据结构的引用计数,如果引用计数为 0,就释放这些结构。磁盘文件则依旧保存在文件系统里。

d)文件读写时的数据流

当进程对一个已打开的文件进行读写时,通常会先访问内核的缓存(Page Cache/Buffer Cache)。如果缓存中没有数据或者缓存失效,则会触发对磁盘文件的实际 I/O。

这就是图中所说的“延迟 fd 读等待缓冲数据”“缓冲区”等概念——内核会将部分文件内容读到内存里,也会把进程写入的数据先放到内存缓存中,然后再同步回磁盘。

“一个进程可以打开多少个文件?可以无限吗?”
1、理论上如果没有操作系统和硬件的限制,打开文件数可以很多,但实际上操作系统会对单个进程以及系统整体可打开文件数做限制。
2、如果打开文件数过多,会导致系统资源耗尽(文件描述符表、内核缓存、内存等),影响稳定性。

磁盘文件与内存文件类似于程序与进程的关系

补充:内核

在计算机系统中,“内核”(Kernel)指的是操作系统的核心组件,它负责管理系统资源和硬件设备,并为用户程序提供各种服务。主要包括以下几个方面:

1、资源管理

内存管理:负责分配和回收内存空间,管理虚拟内存。
CPU调度:决定哪些进程或线程优先获得CPU时间。
设备管理:控制和协调硬件设备(如磁盘、网络、输入/输出设备)的使用。

2、系统调用接口

内核提供系统调用接口,用户程序通过这些接口请求操作系统执行底层操作,如文件读写、网络通信、进程创建等。

3、安全和权限控制

内核负责对系统资源进行保护,确保各个程序在受限的权限下运行,防止恶意访问和破坏。

简单来说,内核就像一个“大管家”,在后台协调各种系统资源,确保整个计算机系统能够高效、稳定地运行。

inode(index node)

什么是 inode?
inode 是文件系统内部的一个数据结构,用来保存一个文件的各种“描述信息”(叫做元数据),而不是文件的实际内容。
每个文件在磁盘上都有一个唯一的 inode(用一个数字来标识)

inode 里包含哪些信息?
文件大小:记录文件有多大。
所有者和权限:谁能读、写、执行这个文件。
时间戳:包括文件最后被访问、修改或状态改变的时间。
数据块指针:指向存储文件实际内容的磁盘块的位置。
硬链接计数:告诉我们有多少个文件名指向这个 inode。

文件系统结构中 inode 的位置
在一个文件系统中,磁盘通常被分成若干块。以 ext2 文件系统为例:
超级块:记录整个文件系统的总体信息。
块组:每个块组中包含了 inode 表(存储所有 inode 的地方)、inode 位图(标记 inode 是否被使用)、数据块位图(标记数据块是否被使用)和数据块(真正存放文件内容)。

文件操作中 inode 的作用
创建文件时:
分配一个空闲的 inode,并把文件的元数据写进去。
分配磁盘数据块,把文件内容写进去。
在目录中记录这个文件名与 inode 号的映射关系。
删除文件时:
系统会减少这个 inode 的硬链接计数。如果计数变成 0,系统会释放 inode 和占用的数据块。

inode(索引节点) 是文件系统中用于描述文件元数据的结构,包含以下信息:
文件大小、所有者、权限、时间戳(访问、修改、属性变更时间)。
文件数据块的存储位置(指向实际数据块的指针)。
硬链接数(记录有多少文件名指向该inode)。

唯一性:每个文件对应一个唯一的inode号,通过 ls -i 可查看

$ ls -i test.c
263715 test.c  # inode号为263715

硬链接与软连接

硬链接

什么是硬链接?
硬链接就是让多个不同的文件名指向同一个 inode,也就是同一个文件。
每个文件名实际上只是这个 inode 的一个“别名”。

举例子讲解:
硬链接(Hard Link):想象你有一个房子(代表实际存储数据),它有一扇门(文件名A)供你进入。当你创建一个硬链接时,就相当于你在房子另一侧又装了一扇门(文件名B),这扇门直接通向同一个房子。无论你从哪扇门进入(A或B),看到的都是同一个房子(数据完全相同)。如果你拆掉一扇门(比如删除文件名A),房子依然存在,你还可以通过另一扇门(文件名B)进入。这就是硬链接:多个名字共享同一个数据块(文件的实际内容和相关信息),它们完全等价。

硬链接的特点
相同 inode 号:多个硬链接文件指向的 inode 号都是一样的。
删除文件:如果删除其中一个硬链接,只是减少了 inode 的链接计数;只要还有其他硬链接存在,文件内容就不会消失。
限制:
不能跨越不同的文件系统(因为 inode 是文件系统内部的)。
通常不允许对目录创建硬链接,防止造成目录结构混乱。
即:
共享数据:两个文件名共同引用同一份数据,修改任一文件的数据都会反映在另一文件上。
删除保护:删除其中一个文件名不会丢失数据,只要还有至少一个硬链接存在。
灵活管理:可以让同一文件在不同位置拥有不同的名称,便于系统管理和备份。

创建一个硬链接:
ln a.txt b.txt
# 这条命令的意思是创建一个硬链接,让文件 b.txt 指向与 a.txt 相同的文件数据。
# 也就是说,系统中会有两个文件名(a.txt 和 b.txt),但它们都指向同一个底层数据(同一个 inode)。

软连接

什么是软链接?
软链接类似于 Windows 系统中的“快捷方式”。它本身是一个独立的文件,里面存储了目标文件的路径。
软链接就像是路边的一块指示牌,上面写着“去房子A”。这块牌本身并不代表房子,而只是告诉你如何去找房子。软链接本身是一个独立的文件,它存储了目标文件的路径。如果目标房子(目标文件)搬走或者被拆除了,这块指示牌(软链接)依然存在,但已经找不到房子了,牌上的指引就无效了。

软链接的特点
独立 inode:软链接有自己的 inode,不与目标文件相同。
跨文件系统:可以指向其他文件系统中的文件。
删除目标文件:如果原文件被删除,软链接就找不到目标文件,这时称为“悬空链接”。
可以链接目录:软链接不仅可以链接文件,还可以链接目录。


独立存在:软连接有自己的文件标识(自己的 inode),但它的内容只是一条指向目标文件路径的指针。
跨分区:软连接可以指向其他磁盘分区的文件,因为它只是保存路径,不直接关联底层存储信息。
原文件删除问题:如果目标文件被删除了,软连接就“失效”了,因为它指向的地址已经没有内容。

如果你用 ln -s a.txt c.txt 创建软链接,c.txt 里面保存的是“a.txt”的路径。当你访问 c.txt 时,系统会读取里面的路径,然后找到 a.txt 的内容。删除时:如果 a.txt 被删除了,c.txt 依然存在,但它指向的位置已经没有数据了,访问 c.txt就会出错。

总结

为何需要两种链接?

场景互补:
硬链接:适合需要高效、稳定访问同一数据的场景(如日志文件的多个引用)。
软链接:适合需要动态路径管理或跨文件系统的场景(如版本切换、快捷方式)。

功能差异:
硬链接:直接绑定inode,无额外存储开销,但受限于文件系统和目录支持。
软链接:通过路径间接引用,灵活但依赖路径有效性。

数据安全:
硬链接:删除任一链接不影响数据,需所有链接删除后数据才释放。
软链接:目标文件删除后需手动修复链接,避免悬挂。

动静态库

静态库

什么是静态库?
先举个例子:你打算烤蛋糕,于是你购买了一个专门为烤蛋糕设计的“工具包”,里面包含了搅拌器、量杯等所有必要的工具。你买下这个工具包后,把里面的工具全部带回家,放在自己的厨房里使用。静态库就像这个“工具包”。当你编译程序时(烤蛋糕前的准备),编译器会把库中的代码(工具)直接复制到你的可执行文件(你的厨房中)。这样,不管你把可执行文件(厨房)搬到哪里,它里面都有所有需要的工具(库函数),不会因为找不到外部工具而影响烤蛋糕(程序运行)。

优缺点:
优点:程序独立,运行时不依赖其他外部文件。
缺点:每个程序都需要一份完整的工具包(库代码),占用空间较大。如果工具包有更新,你需要重新制作整个蛋糕(重新编译程序)。

静态库是一组已经编译好的目标代码,被打包成一个文件(在 Linux 上通常以 .a 结尾,在 Windows 上可能是 .lib)。
编译时:当你编译程序时,静态库的代码会直接复制到你的可执行文件中。

动态库

什么是动态库?
假设你住在一个小区,每个住户都在同一个公共厨房里烤蛋糕。公共厨房里已经配备了一整套专业的烤蛋糕工具。你只需要在烤蛋糕时去公共厨房借用这些工具,而不必自己购买和保存一整套。动态库就像公共厨房里的工具。当你编译程序时,程序只记录使用工具的“说明”(工具名称和使用方法),而实际的工具在运行时由操作系统从公共厨房中加载。这样,多个程序(多个住户)都可以共享同一套工具,而不必各自保存一份工具。

优缺点:
优点:程序体积较小,多个程序共享同一份工具;工具更新后,所有使用该工具的程序都能自动使用新版本(前提是接口没变)。
缺点:程序运行时必须能找到公共厨房(动态库文件),如果工具不在公共厨房或路径不对,程序就无法顺利运行。

总结

静态库和动态库主要都是用来封装和复用程序代码的工具,目的是让开发者不必重复编写相同的代码,而可以直接使用已经写好的代码模块。具体来说:

静态库:

用途:在编译时将库中的代码直接嵌入到你的可执行文件中。
作用:你编译出来的程序自带所有必要的代码,不需要在运行时依赖外部文件。
使用场景:适合不希望在部署时再额外管理库文件的情况,比如一些独立运行的程序或需要快速启动的应用。
特点:程序体积较大,更新库代码后需要重新编译依赖程序。

动态库:
用途:在程序运行时按需加载库中的代码。
作用:多个程序可以共享同一份动态库代码,从而节省磁盘空间和内存,更新库代码时只需替换库文件,而不必重新编译所有程序。
使用场景:适合多个程序共同使用同一套功能模块、需要灵活更新或者资源共享的情况。
特点:程序启动时需要找到并加载动态库,如果库文件缺失或路径不对,程序就无法正常运行。

静态库和动态库都是为了提高代码复用性和管理性,只不过静态库在编译时将代码固定进程序,而动态库则在运行时共享使用。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣刷题-热题100题-第27题(c++、python)

21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/merge-two-sorted-lists/description/?envTypestudy-plan-v2&envIdtop-100-liked 常规法 创建一个新链表&#xff0c;遍历list1与list2&#xff0c;将新链表指向list1与list2…

Vue3 其它API Teleport 传送门

Vue3 其它API Teleport 传送门 在定义一个模态框时&#xff0c;父组件的filter属性会影响子组件的position属性&#xff0c;导致模态框定位错误使用Teleport解决这个问题把模态框代码传送到body标签下

windows下安装sublime

sublime4 alpha 4098 版本 下载 可以根据待破解的版本选择下载 https://www.sublimetext.com/dev crack alpha4098 的licence 在----- BEGIN LICENSE ----- TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA12C0 A37081C5 D0316412 4584D…

Java高级JVM知识点记录,内存结构,垃圾回收,类文件结构,类加载器

JVM是Java高级部分&#xff0c;深入理解程序的运行及原理&#xff0c;面试中也问的比较多。 JVM是Java程序运行的虚拟机环境&#xff0c;实现了“一次编写&#xff0c;到处运行”。它负责将字节码解释或编译为机器码&#xff0c;管理内存和资源&#xff0c;并提供运行时环境&a…

【STL】queue

q u e u e queue queue 是一种容器适配器&#xff0c;设计为先进先出&#xff08; F i r s t I n F i r s t O u t , F I F O First\ In\ First\ Out,\ FIFO First In First Out, FIFO&#xff09;的数据结构&#xff0c;有两个出口&#xff0c;将元素推入队列的操作称为 p u …

20250330-傅里叶级数专题之离散时间傅里叶变换(4/6)

4. 傅里叶级数专题之离散时间傅里叶变换 20250328-傅里叶级数专题之数学基础(0/6)-CSDN博客20250330-傅里叶级数专题之傅里叶级数(1/6)-CSDN博客20250330-傅里叶级数专题之傅里叶变换(2/6)-CSDN博客20250330-傅里叶级数专题之离散傅里叶级数(3/6)-CSDN博客20250330-傅里叶级数专…

漏洞挖掘---迅饶科技X2Modbus网关-GetUser信息泄露漏洞

一、迅饶科技 X2Modbus 网关 迅饶科技 X2Modbus 网关是功能强大的协议转换利器。“X” 代表多种不同通信协议&#xff0c;能将近 200 种协议同时转为 Modbus RTU 和 TCP 服务器 。支持 PC、手机端等访问监控&#xff0c;可解决组态软件连接不常见控制设备难题&#xff0c;广泛…

网络安全之前端学习(css篇2)

那么今天我们继续来学习css&#xff0c;预计这一章跟完后&#xff0c;下一章就是终章。然后就会开始js的学习。那么话不多说&#xff0c;我们开始吧。 字体属性 之前讲到了css可以改变字体属性&#xff0c;那么这里来详细讲一讲。 1.1字体颜色 之前讲到了对于字体改变颜色食…

PS底纹教程

1.ctrlshiftU 去色 2.新建纯色层 颜色中性灰&#xff1b;转换为智能对象 3.纯色层打开滤镜&#xff08;滤镜库&#xff09;&#xff1b; 素描下找到半调图案&#xff0c;数值调成大小5对比1&#xff1b; 再新建一层&#xff0c;素描下找到撕边&#xff0c;对比拉到1&#x…

解决pyinstaller GUI打包时无法打包图片问题

当我们的python GuI在开发时。经常会用到图片作为背景&#xff0c;但是在打包后再启动GUI后却发现&#xff1a;原先调试时好端端的背景图片竟然不翼而飞或者直接报错。这说明图片没有被pyinstaller一起打包…… 要解决这个问题很简单&#xff0c;就是更改图片的存储方式。 tk…

蓝桥杯真题------R格式(高精度乘法,高精度加法)

对于高精度乘法和加法的同学可以学学这几个题 高精度乘法 高精度加法 文章目录 题意分析部分解全解 后言 题意 给出一个整数和一个浮点数&#xff0c;求2的整数次幂和这个浮点数相乘的结果最后四舍五入。、 分析 我们可以发现&#xff0c;n的范围是1000,2的1000次方非常大&am…

Nginx — Nginx安装证书模块(配置HTTPS和TCPS)

一、安装和编译证书模块 [rootmaster nginx]# wget https://nginx.org/download/nginx-1.25.3.tar.gz [rootmaster nginx]# tar -zxvf nginx-1.25.3.tar.gz [rootmaster nginx]# cd nginx-1.25.3 [rootmaster nginx]# ./configure --prefix/usr/local/nginx --with-http_stub_…

回调后门基础

回调后门概述 回调后门&#xff08;Reverse Shell&#xff09;是一种常见的攻击方式&#xff0c;攻击者通过受害主机主动连接到远程服务器&#xff08;攻击者控制的机器&#xff09;&#xff0c;从而获得远程控制权限。 工作原理 受害者主机 运行一个恶意代码&#xff0c;尝…

深度学习 Deep Learning 第13章 线性因子模型

深度学习 Deep Learning 第13章 线性因子模型 内容概要 本章深入探讨了线性因子模型&#xff0c;这是一类基于潜在变量的概率模型&#xff0c;用于描述数据的生成过程。这些模型通过简单的线性解码器和噪声项捕捉数据的复杂结构&#xff0c;广泛应用于信号分离、特征提取和数…

【个人笔记】用户注册登录思路及实现 springboot+mybatis+redis

基本思路 获取验证码接口 验证码操作用了com.pig4cloud.plugin的captcha-core这个库。 AccountControl的"/checkCode"接口代码&#xff0c;通过ArithmeticCaptcha生成一张验证码图片&#xff0c;通过text()函数得到验证码的答案保存到变量code&#xff0c;然后把图…

聚类(Clustering)基础知识3

文章目录 一、聚类的性能评价1、聚类性能评价&#xff08;1&#xff09;聚类性能评价方法&#xff1a; 2、参考模型 (reference model)&#xff08;1&#xff09;数据集&#xff1a;&#xff08;2&#xff09;聚类结果&#xff1a;&#xff08;3&#xff09;参考模型&#xff1…

RK3588使用笔记:设置程序/服务开机自启

一、前言 一般将系统用作嵌入式设备时肯定要布置某些程序&#xff0c;这时候就需要对程序设置开机自己&#xff0c;否则每次都要人为启动&#xff0c;当有些嵌入式系统未连接显示屏或者无桌面环境去操作启动程序时&#xff0c;程序自启就是必须的了&#xff0c;本文介绍在纯li…

python实现股票数据可视化

最近在做一个涉及到股票数据清洗及预测的项目&#xff0c;项目中需要用到可视化股票数据这一功能&#xff0c;这里我与大家分享一下股票数据可视化的一些基本方法。 股票数据获取 目前&#xff0c;我已知的使用python来获取股票数据方式有以下三种: 爬虫获取&#xff0c;实现…

JavaScript DOM与元素操作

目录 DOM 树、DOM 对象、元素操作 一、DOM 树与 DOM 对象 二、获取 DOM 元素 1. 基础方法 2. 现代方法&#xff08;ES6&#xff09; 三、修改元素内容 四、修改元素常见属性 1. 标准属性 2. 通用方法 五、通过 style 修改样式 六、通过类名修改样式 1. className 属…

ARM向量表

向量表作用说明RVBAR在 AArch64 中&#xff0c;重置向量不再是异常向量表的一部分。 有复位向量的专用配置输入引脚和寄存器。在 AArch64 中&#xff0c;处理器从 IMPLEMENTAION‑DEFINED 地址开始执行&#xff0c; 该地址由硬件输入引 脚RVBARADDR定义&#xff0c; 可以通过 R…