当前位置: 首页 > news >正文

【Linux】文件系统:文件fd

Alt

🔥个人主页Quitecoder

🔥专栏linux笔记仓

Alt

目录

    • 01.回顾C文件接口
    • 02.系统文件I/O
      • 02.1 open
        • `flags` 参数(文件打开模式)标记位传参
        • 1. 访问模式(必须指定一个)
        • 2. 额外控制标志(可选,可组合使用)
        • 3. `mode` 参数(仅 `O_CREAT` 生效)
      • 02.2 open函数返回值fd(文件描述符)
    • 03.fd理解

01.回顾C文件接口

#include<stdio.h>int main()
{FILE *fp=fopen("log.txt","w");if(fp==NULL){perror("fopen");return 1;}fclose(fp);return 0;
}

我们进行文件操作,前提是我们的代码跑起来了,文件的打开和关闭,是cpu在执行我们的代码

打开文件:本质是进程打开文件

文件没有被打开的时候,存储在磁盘中

一个进程可以打开多个文件,系统中可以启动很多进程,OS内部一定存在大量被打开的文件,操作系统对这些文件进行管理(先描述再组织,类似PCB)

文件=属性+内容

FILE *fp=fopen("log.txt","w");
  1. 如果不存在,则在当前路径下,新建指定的文件
  2. 默认打开文件的时候,会把目标文件清空

在这里插入图片描述
在这里插入图片描述
> 可以用来新建文件,清空文件,先清空再写入

输出重定向一定是文件操作!

打开文件的方式:

 r Open text file for reading. The stream is positioned at the beginning of the file.r+ Open for reading and writing.The stream is positioned at the beginning of the file.w Truncate(缩短) file to zero length or create text file for writing.The stream is positioned at the beginning of the file.w+ Open for reading and writing.The file is created if it does not exist, otherwise it is truncated.The stream is positioned at the beginning of the file.a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.a+ Open for reading and appending (writing at end of file).The file is created if it does not exist. The initial file positionfor reading is at the beginning of the file, but output is always appended to the end of the file.
模式描述文件指针位置文件是否会创建文件是否会被截断(清空)
r只读模式,文件必须存在开始位置
r+读写模式,文件必须存在开始位置
w写入模式,文件不存在时会创建,存在时会清空文件开始位置
w+读写模式,文件不存在时会创建,存在时会清空文件开始位置
a追加模式,文件不存在时会创建,存在时内容追加到文件末尾文件末尾
a+读写追加模式,文件不存在时会创建,存在时内容追加到文件末尾开始位置(读取)/文件末尾(写入)

02.系统文件I/O

文件->磁盘->外设->硬件

向文件中写入,本质是向硬件中写入,用户没有权利直接写入,通过OS写入,OS必须给我们提供系统调用

fopen/fwrite/fread/fprintf/scanf/printf/cin/cout 我们用的c/c++都是对系统调用接口的封装

02.1 open

在这里插入图片描述

open 是 Unix/Linux 系统中用于打开或创建文件的系统调用,位于 fcntl.h 头文件中。它用于以不同的模式访问文件,如只读、写入、追加等。

1. open 函数原型
在 C 语言中,open 的函数原型如下:

#include <fcntl.h>  // 文件控制选项
#include <sys/types.h>  // 类型定义
#include <sys/stat.h>  // 文件属性
#include <unistd.h>  // 通用 APIint open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

2. 参数解析

  • pathname:要打开的文件路径。
  • flags:指定文件的访问模式(只读、读写等)和其他选项(创建文件、截断等)。
  • mode:用于设置新文件的权限(仅当 O_CREAT 选项被使用时有效),通常采用 06440666 形式。

3. 返回值

  • 成功:返回一个文件描述符(非负整数),用于后续的 readwriteclose 操作
  • 失败:返回 -1,并设置 errno 变量来指示错误类型。

flags 参数(文件打开模式)标记位传参

在系统调用(如 open())中,flags 是一个 位掩码(bitmask),用于控制函数的行为。例如,在 open() 中,flags 用于指定文件的打开模式(只读、只写、读写等)以及额外的选项(创建、追加、非阻塞等)。

位掩码 是指使用二进制位的不同组合来表示多种选项,这样可以通过按位或 (|) 来组合多个标志,而不会相互影响

1. 访问模式(必须指定一个)

访问模式决定了文件的读写权限,这三者不能同时使用,否则会报错。

标志值(十六进制)说明
O_RDONLY0x0000只读模式(Read Only)
O_WRONLY0x0001只写模式(Write Only)
O_RDWR0x0002读写模式(Read & Write)

示例

int fd = open("file.txt", O_RDONLY);  // 以只读模式打开文件
int fd = open("file.txt", O_WRONLY);  // 以只写模式打开文件
int fd = open("file.txt", O_RDWR);    // 以读写模式打开文件

2. 额外控制标志(可选,可组合使用)

这些标志可以与访问模式组合使用,以改变 open() 的行为。

标志值(十六进制)说明
O_CREAT0x0040若文件不存在,则创建新文件(需要 mode 参数)
O_EXCL0x0080O_CREAT 组合,文件必须不存在,否则失败
O_TRUNC0x0200若文件已存在,则清空文件内容
O_APPEND0x0400追加模式,写入时自动跳到文件末尾
O_NONBLOCK0x0800非阻塞模式打开文件(常用于设备文件、网络通信)
O_SYNC0x101000使 write 操作同步到磁盘,保证数据立即写入
O_NOFOLLOW0x20000如果文件是符号链接,则 open() 失败
3. mode 参数(仅 O_CREAT 生效)

flags 包含 O_CREAT 时,需要提供 mode 参数,表示新建文件的权限,例如:

open("newfile.txt", O_WRONLY | O_CREAT, 0644);

其中 0644 代表:

  • 0:八进制数前缀
  • 6110):用户(拥有者)可读可写
  • 4100):组(Group)只读
  • 4100):其他人(Others)只读

如何组合 flags
由于 flags位掩码(bitmask),可以使用按位或 | 运算符来组合多个标志。例如:

int fd = open("file.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
  • O_RDWR(读写模式)
  • O_CREAT(如果文件不存在,则创建)
  • O_TRUNC(如果文件已存在,则清空内容)

等价于:

flags = 0x0002 | 0x0040 | 0x0200;  // 计算出的十六进制值

flags 具体的二进制表示
假设 flags 组合如下:

int flags = O_RDWR | O_CREAT | O_APPEND; 

如果 O_RDWR = 0x0002O_CREAT = 0x0040O_APPEND = 0x0400,那么它们的二进制表示如下:

O_RDWR    = 0000 0000 0000 0010  (0x0002)
O_CREAT   = 0000 0000 0100 0000  (0x0040)
O_APPEND  = 0000 0100 0000 0000  (0x0400)
--------------------------------
组合后    = 0000 0100 0100 0010  (0x0442)

open() 处理 flags 时,它会解析这个二进制值,并执行相应的操作。

  • flagsopen()核心参数,用于控制文件的访问模式和特殊行为。
  • 访问模式(O_RDONLYO_WRONLYO_RDWR必须指定一个
  • 可以通过按位或 | 组合多个控制标志(如 O_CREATO_TRUNCO_APPEND)。
  • mode 参数用于 O_CREAT,指定新文件的权限,如 0644
  • open() 返回文件描述符(fd),失败时返回 -1 并设置 errno

这种flags的传递位图标记位的方法在OS系统调用接口中很常见,我们可以自己设计一个传递位图标记位的函数:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>#define ONE 1       //1 0000 0001
#define TWO (1<<1)   //2 0000 0010
#define THREE (1<<2) //4 0000 0100
#define FOUR (1<<3)  //8 0000 1000void print(int flag)
{if(flag&ONE)printf("one\n");if(flag&TWO)printf("two\n");if(flag&THREE)printf("three\n");if(flag&FOUR)printf("four\n");
}int main()
{print(ONE);printf("\n");print(TWO);printf("\n");print(THREE);printf("\n");print(ONE|TWO);printf("\n");print(ONE|THREE);printf("\n");print(ONE|TWO|THREE|FOUR);printf("\n");return 0;
}

演示了如何使用位运算来检查不同的标志(flag)。程序中的关键部分是 print 函数,它检查传入的 flag 参数,并根据不同的位值输出相应的文本。

让我们逐步分析每个部分。


宏定义

#define ONE 1       //1 0000 0001
#define TWO (1<<1)   //2 0000 0010
#define THREE (1<<2) //4 0000 0100
#define FOUR (1<<3)  //8 0000 1000

这部分定义了四个宏,每个宏的值都代表一个特定的二进制位:

  • ONE = 1 :二进制 0000 0001,表示第 0 位(从右向左数)。
  • TWO = 2 :二进制 0000 0010,表示第 1 位。
  • THREE = 4 :二进制 0000 0100,表示第 2 位。
  • FOUR = 8 :二进制 0000 1000,表示第 3 位。

使用 1 << n 来左移 1 位 n 次,从而生成一个表示 2 的幂的二进制值。


print 函数

void print(int flag)
{if(flag&ONE)printf("one\n");if(flag&TWO)printf("two\n");if(flag&THREE)printf("three\n");if(flag&FOUR)printf("four\n");
}

print 函数通过位运算 &(按位与运算)检查给定 flag 中每一位是否设置为 1。如果某一位为 1,就会输出相应的文本。

  • flag & ONE:检查 flag 的第 0 位(ONE)。
  • flag & TWO:检查 flag 的第 1 位(TWO)。
  • flag & THREE:检查 flag 的第 2 位(THREE)。
  • flag & FOUR:检查 flag 的第 3 位(FOUR)。

输出说明:

  1. print(ONE) 传入 ONE(即 1,二进制 0000 0001),因此检查到第 0 位为 1,输出 one
  2. print(TWO) 传入 TWO(即 2,二进制 0000 0010),因此检查到第 1 位为 1,输出 two
  3. print(THREE) 传入 THREE(即 4,二进制 0000 0100),因此检查到第 2 位为 1,输出 three
  4. print(ONE | TWO) 传入 ONE | TWO(即 1 | 2 = 3,二进制 0000 0011),因此第 0 位和第 1 位都为 1,输出 onetwo
  5. print(ONE | THREE) 传入 ONE | THREE(即 1 | 4 = 5,二进制 0000 0101),因此第 0 位和第 2 位都为 1,输出 onethree
  6. print(ONE | TWO | THREE | FOUR) 传入 ONE | TWO | THREE | FOUR(即 1 | 2 | 4 | 8 = 15,二进制 0000 1111),因此所有四个标志位都为 1,输出 onetwothreefour

onetwothreeone
twoone
threeone
two
three
four

这个例子很有用,展示了如何使用位操作进行标志位管理,尤其是在处理多个选项或功能时


4. openfopen 的区别

对比项open(系统调用)fopen(标准库函数)
头文件<fcntl.h><stdio.h>
返回值文件描述符(intFILE* 指针
模式需要手动指定 flags类似 "r", "w", "a"
缓冲无缓冲,直接访问内核有缓冲,性能更优
适用场景底层 I/O 操作高级文件读写操作
  • 如果只是进行简单的文件读写,建议使用 fopen,因为它提供了缓冲,效率更高
  • 如果需要进行更底层的文件控制(如非阻塞、文件锁定等),则使用 open

02.2 open函数返回值fd(文件描述符)

write函数原型:

#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);
int main()
{umask(0);int fd=open("file.txt",O_WRONLY | O_CREAT,0666);if(fd<0){perror("open");return 1;}const char *message = "hello linux\n";write(fd,message,strlen(message));close(fd);return 0;
}

在这里插入图片描述
此时如果我们重新写入aaaaa:

在这里插入图片描述
这里的文件内容老的没有被清空,这里跟open那里fd传入flags参数有关,我们这里传入O_TRUNC,每次打开文件时清空即可

在这里插入图片描述

int fd=open("file.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);

写方式打开,不存在就创建,存在就先清空!

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

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

在这里插入图片描述

所以,可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发

接下来看fd

fd是open的返回值,也是文件描述符,我们这里设置代码来打印出它的值

int main()
{int fda=open("loga.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fda:%d\n",fda);int fdb=open("logb.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fdb:%d\n",fdb);int fdc=open("logc.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fdc:%d\n",fdc);int fdd=open("logd.txt",O_WRONLY|O_CREAT|O_APPEND,0666);printf("fdd:%d\n",fdd);return 0;
}

在这里插入图片描述
文件描述符数字为3 4 5 6

Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.
0,1,2对应的物理设备一般是:键盘,显示器,显示器

C 语言的标准流与操作系统的文件描述符是关联的。

  • 标准输入(stdin):与文件描述符 0 相关联。
  • 标准输出(stdout):与文件描述符 1 相关联。
  • 标准错误(stderr):与文件描述符 2 相关联

这些文件描述符在程序启动时由操作系统自动分配并打开,且在大多数情况下它们指向终端或控制台。如果没有显式地进行文件重定向(例如使用freopen 或命令行中的重定向符号),这些文件描述符就会继续指向终端

ssize_t write(int fd, const void *buf, size_t count);

那么我们可以直接往显示器上写入:

const char *message = "aaaaa\n";
write(1,message,strlen(message));

在这里插入图片描述

03.fd理解

在这里插入图片描述
系统中有进程被task_struct管理,有很多被打开的文件,struct file 是操作系统用来表示打开文件的主要数据结构。每当一个文件被打开时,操作系统会创建一个 struct file 对象,并将其与文件描述符关联,对象之间通过双向链表连接

struct file {struct file_operations *f_op;  // 文件操作的指针void *private_data;            // 私有数据,用于存储文件的额外信息(如文件特定的数据结构)unsigned long f_flags;         // 文件标志,描述文件的访问模式(如只读、只写、追加等)struct inode *f_inode;         // 文件的 inode 节点,包含文件的元数据off_t f_pos;                   // 文件指针,记录当前文件的读写位置
};

struct file有指向它的缓存,磁盘中文件,属性来初始化struct file,内容加载到缓存中,未来想读修改写入直接在缓存总写入,最后刷新到磁盘中,所以对文件的管理转化为对内核struct file进行管理

那么系统中有很多的进程,右边有很多被打开的文件,那么哪些文件对应哪些进程呢?

进程是可以打开多个文件的,操作系统在PCB里存在一个属性,这个属性叫做struct files_struct *files

在这里插入图片描述

struct files_struct 包含一个数组,数组有对应的下标,进程需要找到一个文件,最终只需要把数组的下标返回给上层,上层只要拿着int fd就可以访问文件了!

所以文件描述符fd的本质是内核的进程的,文件映射关系数组的下标

所以文件一旦打开,我们发现,write,read,close都需要参数fd,一旦fd传入,操作系统就能知道你要访问当前系统的哪个文件

所以读文件就是把缓存中的内容拷贝到应用层,无论读写都必须在合适的时候让0S把文件的内容读到文件缓冲区中,哪怕只修改一个字节,也需要把文件内容读到缓冲区中,再刷到磁盘中

open在干什么呢?

  1. 创建file
  2. 开辟文件缓冲区的空间,加载文件数据(延后)
  3. 查进程的文件措述符表
  4. file地址,填入对应的表下标中
  5. 返回下标

我们已经理解了什么是fd,我们前面提到0 1 2是默认打开了,分别对应键盘,显示器,显示器,三个硬件,如何理解它呢?

我们需要理解,linux,一切皆为文件

在这里插入图片描述
在linux层面上他是怎么做到的呢?

对于每一种设备,我们需要关心的是它的属性和操作方法

最重要的是关注它的操作方法,对于键盘来讲,需要有自己的读方法,写方法,对于显示器,也要有自己的读方法,写方法。冯诺依曼体系中,键盘作为外设,那么这个写方法设置为空函数,显示器对应的读方法也没办法实现

不同的设备,每一种设备的操作方法一定是不一样的,这一层是由驱动层来完成的

每一个被打开的设备,在操作系统层面,为设备构建struct file,虽然底层的方法不同,但是我可以把参数和返回值设为类似的,这里OS设置函数指针。所以如果我们想要访问键盘,找到键盘的struct file,调用read,从struct file视角往上看,上层看到所有的设备一切皆文件

这里是c语言实现的多态技术,进程统一认为struct file

这里的文件层,我们成为虚拟文件系统

虚拟文件系统(VFS,Virtual File System)是操作系统中的一个抽象层,它为不同类型的文件系统(如ext4、NTFS、FAT、NFS 等)提供了一个统一的接口。通过VFS,操作系统能够以一致的方式访问和管理不同类型的文件系统,无论是本地磁盘文件系统还是网络文件系统。这使得文件系统的实现与用户或应用程序的使用方式解耦,增强了操作系统的灵活性和可扩展性

在这里插入图片描述
在操作系统内访问文件时,系统只认文件描述符

那么如何理解c语言通过FILE*访问文件呢?

FILE*:是 C 标准库提供的文件操作接口,它是一个指向 FILE 结构的指针。C 标准库通过 FILE* 为程序员提供了一套更为友好的文件操作函数,如 fopen、fread、fwrite、fclose 等。FILE* 实际上是对文件描述符的封装,提供了缓冲区管理、错误处理等功能

在这里插入图片描述
c语言为什么要这么做?

对于系统调用,不同系统调用接口不一样,这样的代码不具有跨平台性。所有的语言都想有跨平台性,所有的语言对不同平台系统的系统调用进行封装,不同语言封装的时候,文件接口就有差别了

在这里插入图片描述

相关文章:

【Linux】文件系统:文件fd

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.回顾C文件接口02.系统文件I/O02.1 openflags 参数&#xff08;文件打开模式&#xff09;标记位传参1. 访问模式&#xff08;必须指定一个&#xff09;2. 额外控制标志&#xf…...

Vue学习记录19

TransitonGroup <TransitionGroup> 是一个内置组件&#xff0c;用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。 和 <Transtion> 的区别 <TranstionGroup> 支持和 <Transtion> 基本相同的 props、CSS过渡 class 和 JavaScript…...

MATLAB更改图论的布局:设置layout

在图论那一章&#xff0c;我们讲过最小生成树和单源最短路径&#xff08;见&#xff1a;从零开始学数学建模&#xff09;&#xff1a; 以最短路径那节课为例&#xff0c;把绘图pplot那部分代码写为&#xff1a; % plot绘图有很多参数可以设置&#xff0c;使图尽量美观 P plot…...

【分果果——DP(困难)】

题目 分析 分果果题解参考&#xff0c;下面是补充https://blog.csdn.net/AC__dream/article/details/129431299 关于状态 设f[i][j][k]表示第i个人取到的最后一个糖果编号是j&#xff0c;第i-1个人取到的最后一个糖果编号小于等于k时的最大重量的最小值 关于转移方程 关于 j …...

禁止WPS强制打开PDF文件

原文网址&#xff1a;禁止WPS强制打开PDF文件_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何避免WPS强制打开PDF文件。 方法 1.删除注册表里.pdf的WPS绑定 WinR&#xff0c;输入&#xff1a;regedit&#xff0c;回车。找到&#xff1a;HKEY_CLASSES_ROOT\.pdf删除KWPS.PDF…...

罗技鼠标接收器丢了,怎么用另一个logi接收器重新配对?

1.首先接收器得是logi的&#xff0c;其次看这个接收器是什么类型的&#xff0c;一共有以下3种。&#xff08;这几种接收器都可以给其他logi鼠标用&#xff09; 下图左侧带红标的这个&#xff08;标可能带颜色或者是透明&#xff0c;都一样&#xff09;&#xff0c;叫多设备接收…...

ffmpeg configure 研究2:分析屏幕输出及文件输出的具体过程

author: hjjdebug date: 2025年 02月 17日 星期一 16:57:55 CST description: ffmpeg configure 研究2 分析屏幕输出及文件输出的具体过程 文章目录 0. 执行./configure 命令1. sed: cant read 信息是从哪里来的 ?1.1 find_filters_extern()1.2 find_things_extern() 2. 屏幕输…...

软件内有离线模型,效果也很实用......

今天给大家带来一款超实用的图片画质增强软件&#xff0c;完全不需要联网&#xff0c;随时随地都能用。 图片画质增强 一键增强画质 使用起来也超简单&#xff0c;完全不需要安装。 软件主要有两个功能&#xff1a;图片增强和视频增强。 在使用之前&#xff0c;先确定一下输出…...

Linux下ioctl的应用

文章目录 1、ioctl简介2、示例程序编写2.1、应用程序编写2.2、驱动程序编写 3、ioctl命令的构成4、测试 1、ioctl简介 ioctl&#xff08;input/output control&#xff09;是Linux中的一个系统调用&#xff0c;主要用于设备驱动程序与用户空间应用程序之间进行设备特定的输入/…...

如何通过 prometheus-operator 实现服务发现

在之前的章节中,我们讲解了如何编写一个自定义的 Exporter,以便将指标暴露给 Prometheus 进行抓取。现在,我们将进一步扩展这个内容,介绍如何使用 prometheus-operator 在 Kubernetes 集群中自动发现并监控这些暴露的指标。 部署应用 在 Kubernetes 集群中部署我们的自定…...

认识HTML的标签结构

一、HTML的基本概念 1.什么是HTML&#xff1f; ①HTML是描述网页的一种标记语言&#xff0c;也被称为超文本标记语言【并不是一种编程语言】 ②HTML包含了HTML标签和文本内容 ③HTML文档也称为web页面 2.HTML的标签 HTML的标签通常成对出现&#xff0c;HTML文档由标签和受…...

MySQL 之INDEX 索引(Index Index of MySQL)

MySQL 之INDEX 索引 1.4 INDEX 索引 1.4.1 索引介绍 索引&#xff1a;是排序的快速查找的特殊数据结构&#xff0c;定义作为查找条件的字段上&#xff0c;又称为键 key&#xff0c;索引通过存储引擎实现。 优点 大大加快数据的检索速度; 创建唯一性索引&#xff0c;保证数…...

基于flask+vue的租房信息可视化系统

✔️本项目利用 python 网络爬虫抓取某租房网站的租房信息&#xff0c;完成数据清洗和结构化&#xff0c;存储到数据库中&#xff0c;搭建web系统对各个市区的租金、房源信息进行展示&#xff0c;根据各种条件对租金进行预测。 1、数据概览 ​ 将爬取到的数据进行展示&#xff…...

开源Web主机控制面板ISPConfig配置DNS

ISPConfig 是一个开源的 Web 主机控制面板&#xff0c;特别适合用于构建虚拟主机环境。 它拥有强大的 DNS 管理功能&#xff0c;可以&#xff1a; 管理 DNS 区域 (主区域、辅助区域)。支持多种记录类型。DNSSEC 支持。远程 DNS 服务器管理。 ISPConfig 优点在于专为主机服务设…...

【Python项目】信息安全领域中语义搜索引擎系统

【Python项目】信息安全领域中语义搜索引擎系统 技术简介&#xff1a;采用Python技术、MYSQL数据库等实现。 系统简介&#xff1a;系统主要是围绕着语义搜索展开的&#xff0c;要将输入的文字在爬取数据时能够通过深层次的内涵理解&#xff0c;来更好的查找到与之相关的精准信息…...

网站搭建基本流程

需求分析&#xff1a; 实现网站搭建的过程&#xff1a;首先进行网站的需求性分析 网站可分为前台系统和后台系统&#xff0c;由不同的功能拆分为不同的模块 如下是一个电商网站可以拆分出的模块&#xff1a; 在编写代码前&#xff0c;我们要先对网站进行架构&#xff0c;通过…...

mysql 存储空间增大解决方案

一&#xff1a;查询数据库中表占比比较多的表 SELECT table_name AS "Tables", round(((data_length index_length) / 1024 / 1024), 2) AS "Size (MB)" FROM information_schema.tables WHERE table_schema "自己的数据库名"; …...

深入解析队列与广度优先搜索(BFS)的算法思想:原理、实现与应用

目录 1. 队列的基本概念 2. 广度优先搜索&#xff08;BFS&#xff09;的基本概念 3. 队列在BFS中的作用 4. BFS的实现细节 5. C实现BFS 6. BFS的应用场景 7. 复杂度分析 8. 总结 1. 队列的基本概念 队列&#xff08;Queue&#xff09;是一种先进先出&#xff08;FIFO, …...

Swap to Gather-----

C - 烟销日出不见人 问题陈述 给定一个长度为 NN 的字符串 SS&#xff0c;由 0 和 1 组成。保证 SS 至少包含一个 1。 您可以执行以下操作任意次数&#xff08;可能为零&#xff09;&#xff1a; 选择一个整数 ii (1≤i≤N−11≤i≤N−1)&#xff0c;并交换 SS 的第 ii 个和…...

使用DeepSeek+本地知识库,尝试从0到1搭建高度定制化工作流(自动化篇)

7.5. 配图生成 目的&#xff1a;由于小红书发布文章要求图文格式&#xff0c;因此在生成文案的基础上&#xff0c;我们还需要生成图文搭配文案进行发布。 原实现思路&#xff1a; 起初我打算使用deepseek的文生图模型Janus进行本地部署生成&#xff0c;参考博客&#xff1a;De…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...