Linux 文件系统与 I/O 编程核心原理及实践笔记

文章目录

  • 一、理解文件
    • 1.1 狭义理解
    • 1.2 广义理解
    • 1.3 文件操作的归类认识
    • 1.4 系统角度:进程与文件的交互
    • 1.5 实践示例
  • 二、回顾 C 文件接口
    • 2.1 hello.c 打开文件
    • 2.2 hello.c 写文件
    • 2.3 hello.c 读文件
    • 2.4 输出信息到显示器的几种方法
    • 2.5 stdin & stdout & stderr
  • 三、系统文件I/O
    • 3.1 一种传递标志位的方法
    • 3.2 接口介绍
    • 3.5 3-5 open函数返回值
    • 3.6 文件描述符 fd
      • 3.6.1 0 & 1 & 2
      • 3.6.2 文件描述符的分配规则:最小未使用下标优先
      • 3.6.3 应用场景:重定向的实现
      • 3.6.4 dup2 系统调用
  • 五、缓冲区
    • 5.1 什么是缓冲区
    • 5.2 为什么要引入缓冲区机制
    • 5.3 缓冲类型

一、理解文件

1.1 狭义理解

  • 文件在磁盘里
    *磁盘作为永久性存储介质,通过文件系统(如 EXT4、XFS)管理文件存储。文件系统将磁盘划分为inode(索引节点)和block(数据块)
    • inode:存储文件元数据(权限、所有者、修改时间等),每个文件唯一对应一个 inode。
    • block:存储文件实际数据,大小由文件系统决定(如 4KB)。
      注意:即使 0KB 的空文件也会占用inode 空间(不同文件系统 inode 大小不同,如 EXT4 默认 256 字节),但不占用数据块(block)。
  • 磁盘是外设(输入 / 输出设备)
    对磁盘文件的操作本质是IO(Input/Output),涉及内核与外设的数据交互(如通过 DMA 控制器读写磁盘)。

1.2 广义理解

Linux下一切皆文件
系统将硬件设备、进程信息、通信管道等抽象为文件,通过统一接口管理:

  • 硬件设备
    • 块设备:以块为单位读写(如硬盘 /dev/sda,文件类型 b)。
    • 字符设备:以字符流读写(如键盘 /dev/input/event0,文件类型 c)。
  • 虚拟文件系统
    • /proc:动态映射进程信息(如 /proc/self/exe 是当前进程二进制文件)。
    • /sys:暴露内核设备驱动细节(如 /sys/class/leds/ 控制 LED 灯)。
  • 进程通信
    • 管道文件(类型 p):mkfifo mypipe 创建命名管道。
    • 套接字文件(类型 s):/run/docker.sock 用于 Docker 进程通信。
      这种抽象屏蔽了底层差异,例如读写 /dev/tty1(终端设备文件)与读写普通文件使用相同 API。

1.3 文件操作的归类认识

文件 = 元数据(属性) + 数据内容

  • 元数据
    • 基础属性:权限(rwx)、所有者(uid/gid)、硬链接数(ls -l 第二列)。
    • 时间戳:修改时间(mtime)、状态改变时间(ctime)、访问时间(atime)。
    • 技术属性:inode 编号(ls -i)、文件大小(ls -l 第五列)、块数(ls -s)。
  • 数据内容
    分为文本(ASCII/UTF-8)和二进制(如可执行程序、图片),通过cathexdump等工具查看。
  • 操作分类
    • 内容操作:读写(read/write系统调用)、定位(lseek)、截断(truncate)。
  • 属性操作
    • 修改权限chmod(对应chmod系统调用)。
    • 更改所有者chown(对应chown系统调用)。
    • 查看元数据stat命令(对应stat系统调用,返回struct stat结构体)。

1.4 系统角度:进程与文件的交互

  • 一切文件操作由进程触发
    内核通过 ** 文件描述符(File Descriptor, FD)** 标识进程打开的资源,FD0~1023 的整数(默认:0=stdin1=stdout2=stderr)。
    可通过ls -l /proc/$$/fd查看当前进程打开的文件($$为当前进程 PID)。
  • 系统调用 vs 库函数
    • 系统调用:内核提供的底层接口(如openread),需从用户态陷入内核态,开销较高但更直接。
    • 库函数:C 标准库封装的高层接口(如fopenfread),内部调用系统调用并提供缓存机制(如stdio的缓冲区)。
    • 示例fprintf(stdout, "hello") 最终会调用write(1, "hello", 5)系统调用。
  • 内核如何管理文件
    • 每个打开的文件对应内核中的 file结构体,记录文件位置、引用计数等。
    • 多个进程可通过不同 FD 指向同一file结构体(如父子进程共享文件),实现数据共享。

1.5 实践示例

  1. 查看文件元数据
stat test.txt  # 显示inode、权限、时间戳等详细信息
ls -li test.txt  # 查看inode编号和硬链接数

在这里插入图片描述

  1. 操作设备文件
echo "Hello zkp!" > /home/zkp/linux/25/6/7/file/test.txt  # 向文件写入信息
cat /home/zkp/linux/25/6/7/file/test.txt  # 查看文件内容

在这里插入图片描述

  1. 理解文件描述符
exec 3<> file.txt  # 在当前Shell中打开文件,FD=3可读可写
echo "test" >&3    # 通过FD=3写入文件
cat <&3            # 通过FD=3读取文件
exec 3>&-          # 关闭FD=3

二、回顾 C 文件接口

2.1 hello.c 打开文件

在这里插入图片描述
打开的myfile文件在哪个路径下?

  • 在程序的当前路径下,那系统怎么知道程序的当前路径在哪里呢?
    可以使用 ls /proc/[进程id]命令查看当前正在运行进程的信息:
    在这里插入图片描述
    其中:
  • cwd:指向当前进程运行目录的一个符号链接。
  • exe:指向启动当前进程的可执行文件(完整路径)的符号链接。
    打开文件,本质是进程打开,所以,进程知道自己在哪里,即便文件不带路径,进程也知道。由此OS就能知道要创建的文件放在哪里。

2.2 hello.c 写文件

在这里插入图片描述

2.3 hello.c 读文件

在这里插入图片描述

2.4 输出信息到显示器的几种方法

在这里插入图片描述

2.5 stdin & stdout & stderr

  • C 默认会打开三个输出流,分别是 stdin,stdout,stderr
  • 这三个流的类型都是 FILE*,而 fopen 返回值类型也是文件指针

三、系统文件I/O

我们知道,文件的权限分为 rwx,对应的标志位为 4,2,1。

3.1 一种传递标志位的方法

核心原理:位掩码(Bit Mask)
每个标志对应 唯一的二进制位(如第 0 位、第 1 位…),通过 位运算 组合 / 解析:

  • 设置标志:用 |(按位或)组合多个标志(如 FLAG_A | FLAG_B)。
  • 检查标志:用 &(按位与)判断某一位是否为 1(如 if (flags & FLAG_A))。
#include <stdio.h>// 定义权限标志位(与Linux系统保持一致)
#define PERM_READ   (1 << 2)  // 4: 读权限
#define PERM_WRITE  (1 << 1)  // 2: 写权限
#define PERM_EXEC   (1 << 0)  // 1: 执行权限// 解析权限并打印
void func(int perms) {printf("用户权限: ");printf(perms & USER_PERMS(PERM_READ)   ? "r" : "-");printf(perms & USER_PERMS(PERM_WRITE)  ? "w" : "-");printf(perms & USER_PERMS(PERM_EXEC)   ? "x" : "-");printf("\n");
}int main() {// 组合权限:用户有读写,组有读,其他用户无权限int perms = (PERM_READ | PERM_WRITE)printf("权限掩码(八进制): 0%o\n", perms);  // 输出: 0x6func(perms);return 0;
}

3.2 接口介绍

在这里插入图片描述
参数

  • pathname:要打开或创建的目标文件
  • flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成 flags
    • O_RDONLY:只读打开
    • O_WRONLY:只写打开
    • O_RDWR :读,写打开
      这三个常量,必须指定一个且只能指定一个
    • O_CREAT:若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
    • O_APPEND:追加写

返回值

  • 成功:新打开的文件描述符
  • 失败:-1

open函数具体使用哪个,和具体应用场景相关,如目标文件不存在,需要open创建,则第三个参数表示创建文件的默认权限;否则,使用两个参数的open

writereadcloselseek,类比c文件相关接口。

3.5 3-5 open函数返回值

在认识返回值之前,先来认识一下两个概念:系统调用和库函数

  • 上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
  • open close read write lseek都属于系统提供的接口,称之为系统调用接口

看下面这张图:
在这里插入图片描述
系统调用接口和库函数的关系,一目了然。
所以,可以认为,f# 系列的函数,都是对系统调用的封装,方便二次开发。

3.6 文件描述符 fd

  • 通过对open函数的学习,我们知道了文件描述符就是一个小整数

3.6.1 0 & 1 & 2

  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。
  • 0,1,2对应的物理设备一般是:键盘,显示器,显示器
    所以输入输出还可以采用如下方式:
#include <stdio.h>
#include <sys/types.h>#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>int main()
{char buf[1024];ssize_t s = read(0, buf, sizeof(buf));if (s > 0) {buf[s] = 0;write(1, buf, strlen(buf));write(2, buf, strlen(buf));} return 0;
}

在这里插入图片描述

3.6.2 文件描述符的分配规则:最小未使用下标优先

  1. 默认初始状态
    进程启动时,内核会自动打开 3 个标准文件描述符:
    • 0:标准输入(stdin,默认关联键盘)
    • 1:标准输出(stdout,默认关联终端)
    • 2:标准错误(stderr,默认关联终端)
      因此,首次打开新文件时,文件描述符从 3 开始分配(依次递增:3、4、5…)。
  2. 关闭后复用
    如果进程主动关闭某个文件描述符(如 close(0)),后续调用 open 时,内核会 扫描文件描述符表,选择最小的未被使用的下标 分配给新文件。
    • 例:关闭 0 后,新打开的文件会优先占用 0;
    • 若同时关闭 0 和 2,新打开的文件会依次占用 0、2,再继续递增(如 3、4…)。

代码验证

#include <stdio.h>
#include <unistd.h>   // close
#include <fcntl.h>    // open, O_RDWR, O_CREATint main() {// 1. 初始打开:未关闭默认FD,从3开始int fd1 = open("test1.txt", O_RDWR | O_CREAT, 0644);printf("fd1: %d\n", fd1);  // 输出:3(0、1、2已占用)// 2. 关闭标准输入(FD=0),后续打开优先复用0close(0); int fd2 = open("test2.txt", O_RDWR | O_CREAT, 0644);printf("fd2: %d\n", fd2);  // 输出:0(最小未使用下标)// 3. 关闭标准错误(FD=2),后续打开优先复用2close(2); int fd3 = open("test3.txt", O_RDWR | O_CREAT, 0644);printf("fd3: %d\n", fd3);  // 输出:2(当前最小未使用下标)// 4. 继续打开,下一个最小未使用是3(0、2已用,1仍被stdout占用)int fd4 = open("test4.txt", O_RDWR | O_CREAT, 0644);printf("fd4: %d\n", fd4);  // 输出:3return 0;
}

运行结果

fd1: 3  
fd2: 0  
fd3: 2  
fd4: 3  

3.6.3 应用场景:重定向的实现

  1. 输出重定向示例
# 将命令输出写入文件(本质是修改FD=1的指向)
ls -l > output.txt

实现逻辑:

  • Shell 先关闭 FD=1(标准输出),再打开 output.txt,此时新文件会占用 FD=1;
  • 后续 ls 命令的输出会写入 FD=1(即 output.txt),而非终端。
  1. 代码模拟重定向
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main() {// 1. 关闭标准输出(FD=1)close(1); // 2. 打开新文件,会复用FD=1int fd = open("redirect.txt", O_WRONLY | O_CREAT, 0644);// 3. printf 会向 FD=1 写入(此时指向 redirect.txt)printf("Hello, Redirect!\n"); close(fd);return 0;
}

运行后,redirect.txt 会包含 Hello, Redirect!,而非终端输出

注意事项

  • 关闭默认描述符(如 close(1))后,若后续代码依赖标准输出(如 printf),会导致输出丢失或异常。
  • 建议使用 dup2 实现重定向(安全关闭旧描述符,避免冲突)。

重定向的本质
在这里插入图片描述

3.6.4 dup2 系统调用

在这里插入图片描述

示例:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main() {// 1. 打开文件(获取新的文件描述符,如3)int fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);if (fd == -1) {perror("open failed");return 1;}// 2. 将标准输出(FD=1)重定向到 fd 指向的文件if (dup2(fd, 1) == -1) {perror("dup2 failed");close(fd);return 1;}// 3. 此时 printf 会写入 output.txt,而非终端printf("Hello, dup2!\n");// 4. 关闭 fd(注意:标准输出仍指向 output.txt)close(fd);// 5. 验证:继续向标准输出写入fprintf(stdout, "This will also appear in output.txt\n");return 0;
}

printf是C库当中的IO函数,一般往stdout中输出,但是stdout底层访问文件的时候,找的还是fd:1,但此时,fd:1下标所表示内容,已经变成了myfifile的地址,不再是显示器文件的地址,所以,输出的任何消息都会往文件中写入,进而完成输出重定向。

五、缓冲区

5.1 什么是缓冲区

缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

5.2 为什么要引入缓冲区机制

读写文件时,如果不会开辟对文件操作的缓冲区,直接通过系统调用对磁盘进行操作(读、写等),那么每次对文件进行一次读写操作时,都需要使用读写系统调用来处理此操作,即需要执行一次系统调用,执行一次系统调用将涉及到CPU状态的切换,即从用户空间切换到内核空间,实现进程上下文的切换,这将损耗一定的CPU时间,频繁的磁盘访问对程序的执行效率造成很大的影响。

为了减少使用系统调用的次数,提高效率,我们就可以采用缓冲机制。比如我们从磁盘里取信息,可以在磁盘文件进行操作时,可以一次从文件中读出大量的数据到缓冲区中,以后对这部分的访问就不需要再使用系统调用了,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度

又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。可以看出,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

5.3 缓冲类型

标准I/O提供了3种类型的缓冲区。

  • 全缓冲区:这种缓冲方式要求填满整个缓冲区后才进行I/O系统调用操作。对于磁盘文件的操作通常使用全缓冲的方式访问。
  • 行缓冲区:在行缓冲情况下,当在输入和输出中遇到换行符时,标准I/O库函数将会执行系统调用操作。当所操作的流涉及一个终端时(例如标准输入和标准输出),使用行缓冲方式。因为标准1/O库每行的缓冲区长度是固定的,所以只要填满了缓冲区,即使还没有遇到换行符,也会执行I/0系统调用操作,默认行缓冲区的大小为1024。
  • 无缓冲区:无缓冲区是指标准I/O库不对字符进行缓存,直接调用系统调用。标准出错流stderr通常是不带缓冲区的,这使得出错信息能够尽快地显示出来。

除了上述列举的默认刷新方式,下列特殊情况也会引发缓冲区的刷新:

  1. 缓冲区满时;
  2. 执行flush语句;

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

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

相关文章

1.9 Express

Express 是一个基于 Node.js 平台的轻量级、灵活的 Web 应用框架&#xff0c;它为构建 Web 应用和 API 提供了一系列强大的功能。 核心特性 中间件支持&#xff1a;Express 使用中间件&#xff08;middleware&#xff09;函数来处理 HTTP 请求和响应。中间件可以访问请求对象&…

面壁智能MiniCPM4.0技术架构与应用场景

&#x1f4cb; 目录 1. 引言&#xff1a;端侧智能新时代2. MiniCPM4.0概述3. 核心技术架构 3.1 高效双频换挡机制3.2 稀疏注意力机制3.3 系统级优化创新 4. 技术突破与性能表现5. 应用场景深度解析 5.1 智能手机应用5.2 智能家居场景5.3 汽车智能化5.4 其他端侧应用 6. 行业影…

RabbitMQ路由核心解密:从Exchange到RoutingKey的深度实践与避坑指南

&#x1f50d; RabbitMQ路由核心解密&#xff1a;从Exchange到RoutingKey的深度实践与避坑指南 “消息去哪了&#xff1f;”——这是每位RabbitMQ使用者在调试时最常发出的灵魂拷问。 理解Exchange与RoutingKey的协作机制&#xff0c;正是解开路由谜题的关键钥匙。 一、Exchang…

Spring MVC完全指南 - 从入门到精通

目录 1. Spring MVC简介 2. MVC架构模式 3. Spring MVC核心组件 4. 请求处理流程 5. 控制器详解 6. 请求映射 7. 参数绑定 8. 数据验证 9. 视图解析器 10. 模型数据处理 11. 异常处理 12. 拦截器 13. 文件上传下载 14. RESTful API 15. 配置详解 总结 1. Sprin…

实战使用docker compose 搭建 Redis 主从复制集群

文章目录 前言技术积累1、Redis 主从复制机制2、Docker Compose 编排3、 Redis 配置文件定制4、 验证主从状态5、 自动化部署与维护 环境准备实战演示创建redis目录及配置1、创建redis目录2、创建redis配置文件 启动redis集群服务1、创建docker-compose编排文件2、编排docker-c…

【学习笔记】RTSP-Ovnif-GB28181

【学习笔记】RTSP-Ovnif-GB28181 一、RTSP_RTP_RTCP RTSP&#xff08;Real Time Streaming Protocol&#xff09;&#xff0c;RFC2326&#xff0c;实时流传输协议&#xff0c;是TCP/IP协议体系中的一个应用层协议。 RTP协议详细说明了在互联网上传递音频和视频的标准数据包格…

stm32-c8t6实现语音识别(LD3320)

目录 LD3320介绍&#xff1a; 功能引脚 主要特色功能 通信协议 端口信息 开发流程 stm32c8t6代码 LD3320驱动代码&#xff1a; LD3320介绍&#xff1a; 内置单声道mono 16-bit A/D 模数转换内置双声道stereo 16-bit D/A 数模转换内置 20mW 双声道耳机放大器输出内置 5…

RAG技术全解析:从概念到实践,构建高效语义检索系统——嵌入模型与向量数据库搭建指南

一、RAG技术概述&#xff1a;为什么需要RAG&#xff1f; 1.1 什么是RAG&#xff1f; RAG&#xff08;Retrieval-Augmented Generation&#xff09;是一种结合检索与生成能力的AI架构。其核心思想是通过外部知识库动态增强大语言模型&#xff08;LLM&#xff09;的生成能力&…

【资源分享】手机玩转经典游戏!小鸡模拟器1.9.0:PSP/NDS/GBA完美运行!

阿灿今天给大家推荐一款小鸡模拟器&#xff0c;这是一个老款PC和掌上游戏机模拟器。完美模拟街机&#xff08;fbamamemameplus).PS、PSP、FC(NES)SFC(SNES)、GBA、GBC、MD、NDS、DC、NGP、WS (WSC) PCE、ONS 等18款经典掌机游戏机。小鸡模拟器同时也提供海量热门的汉化版游戏免…

matlab脉冲信号并绘制波形2025.6.11

以下是一个使用MATLAB生成5V、10MHz脉冲信号并绘制波形的示例代码: % 5V 10MHz脉冲信号仿真 clc; clear; close all; % 参数设置 voltage = 5; % 信号幅度(V) frequency = 10e6; % 脉冲频率(10MHz) duty_cycle =

ElasticJob初探

依赖版本 JDK版本是&#xff1a;jdk17 springboot版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version></parent>zookeeper elasticjo…

【Vue3】(三)vue3中的pinia状态管理、组件通信方式及总结、插槽

目录 一、vue3的pinia 1、什么是pinia&#xff1f; 2、为什么Vue3选择pinia&#xff1f; 3、使用pinia的好处 4、安装pinia 2、项目配置 3、存储/读取pinia中的数据 4、修改pinia中的数据 5、storeToRefs&#xff08;保持store中数据的响应式&#xff09; 6、getters 7、…

WEB3全栈开发——面试专业技能点P1Node.js / Web3.js / Ethers.js

一、Node.js 事件循环 Node.js 的事件循环&#xff08;Event Loop&#xff09;是其异步编程的核心机制&#xff0c;它使得 Node.js 可以在单线程中实现非阻塞 I/O 操作。 &#x1f501; 简要原理 Node.js 是基于 libuv 实现的&#xff0c;它使用事件循环来处理非阻塞操作。事件…

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…

web架构4------(nginx常用变量,nginx中英文自动匹配,lnmp网站架构,正向代理,反向代理,负载均衡)

一.前言 本期来介绍nginx最后几个知识点&#xff0c;看着要说的内容很多&#xff0c;其实一点也不多&#xff0c;都是所见即所得的东西。 二.nginx常用变量 2.1 常用变量 $args 请求中的参数&#xff0c;也叫查询参数&#xff0c;如www.123.com/1.php?a1&b2的$args就是…

openeuler系统(CentOs)图形化桌面黑屏/丢失(开启VNC服务冲突)

1. VNC服务开启如下&#xff1a; https://zhuanlan.zhihu.com/p/5049263261 在centos8系统上使用tigervnc-server搭建VNC_centos8 tigervnc-server-CSDN博客 2. 上述操作完成后&#xff0c;连接VNC仍会出现黑屏&#xff0c;则需要编辑/root/.vnc/xstartup&#xff1a; [运维…

MySQL:Prepared Statement 预处理语句

预处理语句&#xff08;Prepared Statements&#xff09;是 MySQL 中一种用于执行 SQL 查询的高效、安全的方法。通过使用预处理语句&#xff0c;可以显著提升查询性能&#xff0c;并防止 SQL 注入攻击。本文将详细介绍 MySQL 预处理语句的概念、使用方法及其优势。 一、预处理…

EPPLUS——CAD c#读写EXCEL的第三方库

EPPLUS(可支持NET35) 在 CAD 的 C# 二次开发中&#xff0c;使用 EPPLUS 库处理 Excel 文件具有以下显著优点&#xff0c;尤其在兼容性、便捷性和性能等方面契合 CAD 项目的需求&#xff1a; 1. 跨.NET 版本兼容性强&#xff0c;适配 CAD 多环境部署 多框架支持&#xff1a;EP…

Linux知识回顾总结----进程状态

本章将会介绍进程的一些概念&#xff1a;冯诺伊曼体系结构、进程是什么&#xff0c;怎么用、怎么表现得、进程空间地址、物理地址、虚拟地址、为什么存在进程空间地址、如何感性得去理解进程空间地址、环境变量是如何使用的。 目录 1. 冯诺伊曼体系结构 1.1 是什么 1.2 结论 …

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…