Linux:文件操作
目录
一、关于文件
1、文件类的系统接口
2、文件的含义
二、文件操作
1、C语言文件相关接口
2、系统接口
open
close
write
read
三、文件描述符
关于fd
fd的分配规则
输出重定向示例
输入重定向示例
追加重定向示例
dup2函数
缓冲区
stdout与stderr
perror
一、关于文件
1、文件类的系统接口
首先不同语言都有不同的文件操作接口,C语言、C++、java都有各自的文件接口,而这些文件接口的底层,其实是封装的系统接口
之所以各个语言不直接使用文件类的系统接口,是因为系统接口相比较各个语言封装出来的接口,难度较大,学习成本比较高,各种语言对系统接口做封装,是为了让接口更好的使用;
其次,也是为了跨平台这个特性,如果每种语言对系统接口不封装,直接调用系统接口,那么所有的文件操作都必须使用操作系统接口,无法在其他平台运行,是不具备跨平台特性的
2、文件的含义
说起文件,大部分人都想的是普通的磁盘文件,例如记事本打开的文本文件、.exe之类的文件
其实站在系统的角度,能够被input读取,output写出的设备都叫做文件,例如:键盘、显示器、磁盘、网卡、显卡等外设,都可以被称为文件
二、文件操作
1、C语言文件相关接口
我们先在Linux中写C语言中学习的文件接口:
以w的方式打开,如果文件不存在,会创建一个新文件,那么这个文件会创建在哪呢
很显然会创建在当前路径下,而当前路径指:一个进程运行起来的时候,每个进程都会记录自己当前所处的工作路径,而这个工作路径就是当前路径
上面的代码中,test.txt这个文件是不存在的,该路径下只有两个文件:
所以在编译运行file.c后,test.txt会在该路径下创建出来:
由于当前进程的工作路径在这里,所以创建出来的test.txt也就在这个路径下了
以w方式打开文件时,不论文件里面是否有内容,打开文件时做的第一件事就是清空文件内容,哪怕我们什么都不干,只是打开关闭文件,文件内容都会被清空,下面举个例子:
我们向文件test.txt中写入"hello"
查看test.txt内容:
这时改变file.c的内容,将fprintf的相关代码删除:
然后再编译运行myfile:
发现test.txt里面的内容没有了,大小为0
有了上面打开文件就会清空文件内容的基础,再看下面的例子:
先cat test.txt,发现文件里没有内容
接着echo输出重定向的方式向test.txt写了一个字符串hello,cat test.txt发现确实写入了
然后执行>test.txt后,再cat,发现又被清空了
这里的>符号,可以当做一个命令,表示要往文件里写入的,而向文件写入首先做的就是打开这个文件,上面也提到了,打开文件做的第一件事就是清空文件内容,所以我们就可以明白为什么执行完>test.txt后,test.txt中内容就被清空了
以上就是复习的C语言相关文件接口
2、系统接口
上面提到的C语言的库函数,底层一定会调用系统调用接口
系统调用接口有open、close、write、read
open
通过man了解一下open:
有三个头文件需要包含,然后看下面的两个open后面的参数
参数pathname:代表需要打开文件的路径 + 文件名
参数flags:表示选项(O_RDONLY、O_WRONLY、O_RDWR必须包含这三个其中一个)
参数mode:表示权限(如果传入0666,就表示拥有者、所属组、other的权限都是rw-)
选项有很多,例如:O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)、O_CREAT(文件不存在就创建)、O_TRUNC(打开文件时如果有原本内容就清空原始内容)
像上面的这些是O_RDONLY、O_WRONLY、O_RDWR,其实就是宏定义,而open后面的参数只有一个flags,如何传递这么多的标记位,这里就和C++中的位图类似了,用比特位传递
关于open的返回值:
如果成功了,会返回一个文件描述符
如果失败了,就会返回-1
关于两个open的使用场景:
三个参数的open是用于文件不存在,第三个参数可以控制该文件的权限
两个参数的open是用于文件已经存在的场景
下面示范一下如何用比特位传递多个标记位:
定义了三个宏A、B、C,分别是0x1(0000 0001)、0x2(0000 0010)、0x4(0000 0100)
main函数中给test传递的参数A | B,就是0000 0001 | 0000 0010即传递上去的值为0000 0011
这时传递上去的0000 0011与A(0000 0001),B(0000 0010)按位与都满足,所以会打印里面的语句
运行结果为:
满足传上去的参数要求
这里的例子就说明了,如果想传入多个标志位,则用 | (按位或)的方式就能做到,下面会用到这个结论
下面使用一下open:
首先第一个umask是一个函数,用于在当前进程重置umask值,以便于我们open中传递的第三个关于权限的参数受到系统中umask值的影响
open中的第二个参数,O_WRONLY | O_CREAT,O_WRONLY是以w的方式打开,O_CREAT是创建一个文件,如果文件不存在必须要加上O_CREAT选项,中间的|在上面的例子中说到过,传递多个标志位时用|连接
运行结果如下:
成功运行
close
通过man查看close
这里的close使用就很简单了,包含一个头文件unistd.h
关闭文件时,将刚刚返回的文件标识符传入即可
代码中添加close即可:
write
通过man查看write
包含一个头文件unistd.h
参数的含义就是:向一个fd里,写特定的buf,字符个数是count个
下面演示用法:
我们给了一个const char*类型的字符串,使用write接口
运行结果如下:
成功向文件中写入了I am write
但是这里会有一个问题,我们在C语言中,写入文件时,如果文件中有内容,再重写其他内容时会被覆盖,而在Linux中则会存在问题,如下:
将字符串str改为"111",然后在运行,查看现在test.txt中的内容:
可以看到,并不是我们所想的111,而是111覆盖了刚刚内容的前三个字符的位置,反而test.txt中的内容变为了111m write
想解决这个问题,只需要加上选项O_TRUNC,即创建文件时如果有原始内容,则清空原始内容
如下所示:
此时再重新运行,打印test.txt中内容就变为我们想要的样子了:
这里也应证了我们最开始所说的文件类的系统接口学习成本比较高,难度比较大,所以各种语言会封装文件接口,使用起来更简单些
我们使用的 open("test.txt",O_WRONLY|O_CREAT|O_TRUNC,0666)
与C语言中的fopen("test.txt","w")的功能是一样的,更看出其中的难易
上面用的是w的功能,如果是a(追加),只需将O_TRUNC换为O_APPEND即可:
这时多运行几次,结果为:
这时代码的open("test.txt",O_WRONLY|O_CREAT|O_APPEND,0666)
与C语言的fopen("test.txt","a")功能相同
read
通过man查看read
同样包含一个头文件unistd.h
参数的含义就是:从特定的文件描述符fd读取数据,读到buf里面,读取的个数是count个
我们先向text.txt中写入数据:
接着使用read:
首先将open后面的参数变为O_RDONLY,只读,然后创建一个buf的字符数组,memset将buf中的数据全部置为'\0',read读文件,最后打印出读取的内容:
最终读取成功
三、文件描述符
关于文件描述符fd,上面的代码中有打印过,接下来将代码做以改造,多打开几个文件,再观察文件描述符:
创建4个test.txt文件,观察每次返回的文件描述符fd:
可以看到test.txt1~4的文件描述符分别是3、4、5、6,那么为什么是从3开始的,0、1、2是对应的什么,其实在C语言中我们就学过了,0、1、2分别对应的是stdin(标准输入)、stdout(标准输出)、strerr(标准错误),是被默认打开的
stdin、stdout、strerr他们的类型都是FILE*的
下面举例验证一下0、1、2这三个文件描述符:
我们C语言中使用的fprintf,如果要往显示器上写,第一个参数就是stdout
而系统接口write,第一个参数是fd,我们可以传入1,观察是不是往显示器上写入:
结果为:
可以发现,传入文件描述符1,也是往显示器上写入的,与stdout功能相同
下面示例文件描述符为0的stdin
系统接口read的第一个参数传入0,表示stdin
read的返回值是读入的个数,如果大于0,就说明读入成功了
结果为:
可以看到,也可以通过传入文件描述符0,实现stdin的功能
关于fd
fd的本质是指针数组的下标
在内核中,每一个进程都是可以打开多个文件的,也就是一对多的关系
而为了管理这些文件,操作系统需要构建一个file结构体,包含了被打开文件的几乎全部内容,如果被打开的文件很多,就用双链表组织起来
而我们刚刚说到的0、1、2,就是一个指针数组的下标,表示这个指针数组前三个位置存储的就是stdin、stdout、stderr的位置,Linux进程默认会打开这三个文件描述符,0、1、2对应的物理设备一般是:键盘、显示器、显示器
这里的指针数组中的每一个元素都是一个指向打开文件的指针
而我们上面所举例子中新创建了4个test.txt文件,他们返回的fd分别是3、4、5、6,也就代表着他们所在的位置就是这个指针数组的3、4、5、6下标,在数组中做哈希索引,索引之后就能找到被打开的文件对象
进程打开一个文件,操作系统会创建一个struct file对象,然后在该进程的指针数组中,分配一个没有被使用的数组空间,接着把新的文件地址填在这里面,然后返回对应的文件描述符下标给用户使用,所以fd在内核中,本质是一个指针数组的下标
fd的分配规则
fd的分配规则是:优先最小的,没有被占用的文件描述符
正常情况下,我们创建一个新文件,文件描述符是3,因为0、1、2是默认被打开的
结果为:
如果我们提前把文件描述符0关了(close),那么新创建一个文件会被分配到哪个文件描述符:
这时结果为:
所以可以明白,文件描述符基本的分配规则就是:从头遍历,找最小的且没有被占用的文件描述符
输出重定向示例
那么如果close的是1呢,如图:
创建test.txt前,close(1),观察现象:
我们运行myfile,没有任何内容,但是cat查看test.txt时却发现,本该打印在显示器上的内容出现在了test.txt中
这是因为,在我们创建test.txt前,关闭了文件描述符1,也就是系统默认打开的stdout,它所对应的指针数组下标为1的位置为空了,这时创建test.txt,按照fd的分配原则,将文件描述符1就分配给了test.txt
而我们所使用的printf、fprintf中,都是包含stdout的,所以执行时默认就是执行了stdout,而stdout本身默认的文件描述符就是1,刚刚分配文件描述符是底层做的,上层并不清楚,所以它们就照常往1里面写,但是写完后,通过进程找到指针数组,再通过指针数组的下标1找到所对应的文件,而这时1所对应的文件早已不是stdout,而是test.txt,因此我们printf的内容都在test.txt中可以看到
本来应该显示到显示器的内容,被写入到了文件中,这就是输出重定向
以上所说的就叫做重定向的原理!
重定向的本质:其实是在操作系统内部,更改fd对应的内容的指向
输入重定向示例
先正常使用fgets函数,观察正常打印的结果:
创建了一个test.txt文件,理应分配的文件描述符是3
并且下面的fgets第三个参数是stdin,是从键盘读取的
所以先打印fd:3,然后在键盘输入hello,显示器就打印了一个hello
上面是正常情况,下面演示输入重定向的情况,即close(0)时的情况:
首先我们将test.txt的内容更改为hello test
然后在open文件test.txt前,close(0):
这时根据fd的分配规则,显然test.txt的文件描述符就分配为了0
运行结果为:
可以看到,打印出fd:0,但是接下来本应该从键盘读取,却变为了直接读取文件test.txt的内容
原因也很简单,我们close(0)后,原本数组下标为0的的位置是指向stdin的,现在变为了指向文件test.txt,而上层并不知道底层做了这些改变,在执行fgets时依然是从文件描述符0中读取,而这时文件描述符已经变为了test.txt,所以执行时,根据文件描述符0指向的地址是test.txt的位置,并不是stdin的,所以不需要等待从键盘输入再打印,而是直接打印test.txt的内容
而上面所说的,本来应该从键盘中读取的内容,变为了从文件中读取,这就是输入重定向的定义!
追加重定向示例
这是上面所举例的输出重定向
追加重定向只需将open中的参数O_TRUNC(清空)改为O_APPEND(追加)即可
这时看结果:
第一次执行,打印了原有的内容hello test,且追加了fd:1
又对执行了两次,可以看到test.txt的内容也多了两行内容
这就是追加重定向
dup2函数
而我们如果想实现重定向,上面的方法可以是可以,但是比较麻烦,下面说说更好的方法去实现重定向
首先学习函数dup2
dup2中有两个参数oldfd和newfd
关于这两个参数需要详细说明:
oldfd是要拷贝到newfd中去,所以最终会留下oldfd
所以如果我们创建一个文件,这个文件的文件描述符就是3,这时要进行输出重定向,即将文件描述符1(stdout[显示器])改变指向,所以需要将3拷贝到1中去,最后留下的就是3,即所创建的文件了
所以实现输出重定向使用dup2时,oldfd是3,newfd是1,具体示例如下:
使用fprintf时顺便复习一下命令行参数,这时结果为:
如果我们直接执行myfile这个可执行文件,就进入第一行语句if (argc != 2)中了,因为此时只有myfile,argc == 1
接下来我们在myfile后面跟上了一个字符串,这时就符合要求,也打印出来了我们输入的字符串
以上是不使用dup2的情况,下面使用dup2进行输出重定向:
上面说到的,第一个参数是oldfd,第二个参数是newfd,要保留oldfd,所以我们传入fd,即test.txt的fd
观察结果:
dup2函数实现了输出重定向
dup2函数追加重定向:
只需将open的第二个参数中的O_TRUNC变为O_APPEND即可:
结果为:
也能很轻松地实现
缓冲区
缓冲区就是一段内存空间
有缓冲区能够提高整机的效率,也能够提高用户的响应速度
缓冲区的刷新策略:
1、立即刷新
2、行刷新(行缓冲,例如遇到\n)
3、满刷新(全缓冲)
也存在特殊情况:
1、用户强制刷新(例如fflush)
2、进程退出
一般采用行缓冲策略的设备文件是显示器,采用全缓冲策略的是磁盘
而所有的设备都是倾向于全缓冲的,因为缓冲区满了才刷新,IO操作少,访问外设的次数变少,从而提高效率
设备是倾向于全缓冲,但是其他的刷新策略,都是根据具体情况所做出的改变:
例如显示器是行缓冲刷新,是因为显示器是直接给用户看的,需要照顾用户体验
下面看一个例子:
先执行printf、fprintf、fputs,然后执行write,最后调用fork()
在调用fork()时,上面的函数已经执行完毕了
下面观察结果:
编译后直接运行myfile,发现在显示器上打印的是4行
但是向普通文件打印时,却变成了7行
通过观察可以发现,C语言的接口是打印了两次的,而系统接口只打印了一次
通过这个结果,我们可以看出来,执行fork()后,并不影响系统接口,所以如果存在缓冲区,是由C标准库提供的,而不是操作系统提供,因为如果是操作系统提供的,那么上面的结果应该是一样的,write也应该打印两次
所以如果我们使用fprintf、fputs等接口,应该是先写入C标准库的缓冲区中,然后我们就不需要关心了,何时刷新都是由C标准库管理的
而如果使用的是write接口,就会直接将数据写给操作系统,不需要经过缓冲区
下面说明上面代码在显示器上打印,和重定向到文件中,为什么结果不一样的原因:
第一,如果向显示器打印,这时的刷新策略是行刷新,每遇到一个\n就刷新一次,那么最后执行fork的时候,一定是函数执行完了并且数据已经被刷新了,此时的fork无意义!所以在显示器上打印时,只有4个结果
第二, 如果你进行了重定向,就变为了要向磁盘文件打印,这时的刷新策略变成了全缓冲!所以printf、fprintf、fputs字符串后面的\n便没有意义了,此时执行fork函数,有父进程和子进程,而父进程的数据还在缓冲区当中,fork函数后面就执行return 0即进程退出
上面说到特殊情况,进程退出时会刷新缓冲区,而刷新的过程其实就是写入的过程,可以理解为一个进程退出时为了不影响另一个进程使用现有的数据,所以会发生写时拷贝,所以我们明白了,上面凡是在C标准库的缓冲区的数据,都出现了两份,而直接直接写给操作系统的系统接口,只有一份
上面了解到,之所以打印到显示器上内容和打印到文件里的内容不一样,是因为打印到文件里时,改变了刷新策略,变为了全缓冲,导致父进程的数据没有被刷新出来,还保存在缓冲区中,所以执行fork后,发生写时拷贝,打印出来了2份数据
那如果我们在fork前,执行fflush函数,强制刷新缓冲区,这时执行fork时,缓冲区中没有数据,是不是就像我们所推测的那样,上面两种方式打印的内容就相同了,如下图:
观察结果:
通过观察可以发现,执行完fflush后,两种方式的打印的内容就完全相同了
stdout与stderr
stdout与stderr对应的文件描述符分别是1和2
而1和2对应的都是显示器文件,但是它们是不一样的
在输出或追加重定向时会有区别:
我们分别在打印时加上->区别是1还是2
下面看结果,正确运行时,都能打印到显示器上:
如果输出重定向:
我们会发现,往2号文件描述符写的内容依旧打印到显示器上了,而只有往1号文件描述符写的内容才重定向到文件中
所以我们明白了,这里的重定向其实是往1号文件描述符写的
1和2对应的都是显示器文件,可以理解为打开了两份,重定向时把正确的信息写到文件里,错误信息依旧打印到显示器上
因此一般情况下,如果程序可能存在问题,建议使用stderr或cerr来打印
如果是常规的文本文件,建议使用stdout或cout打印
针对标准输出和标准错误,如果我们想将这两种分开打印,可以进行如下操作:
这时就可以将调用stdout的打印到right.txt中,调用strerr的打印到err.txt中了
我们可以将标准输出和标准错误分开,2>err.txt就是将本来应该显示到2号文件描述符的内容显示到err.txt上
那如果我们就是想将stdout和stderr的内容都放在一个文件中,就可以进行如下操作:
这时就能实现上述要求
perror
上面代码中出现了perror这个函数,其实我们可以发现使用perror后,打印结果多了一个success,其实这个函数会自动根据全局的错误码,输出对应的错误原因
例如我们使用open时,经常在下面的if语句里,使用perror("open"),就是表示,如果open失败了,可以打印失败的错误信息
假设我们使用open,去读test文件,if语句中使用perror
打印结果如下:
通过ls可以发现,当前路径下并没有test文件,所以open的返回值小于0,即进入if语句执行perror
通过结果可以看到,perror会自动调用错误码输出错误信息,例如上述例子的错误信息就是不存在该文件
相关文章:

Linux:文件操作
目录 一、关于文件 1、文件类的系统接口 2、文件的含义 二、文件操作 1、C语言文件相关接口 2、系统接口 open close write read 三、文件描述符 关于fd fd的分配规则 输出重定向示例 输入重定向示例 追加重定向示例 dup2函数 缓冲区 stdout与stderr perror…...

vue源码笔记之——运行时runtime
源码中的位运算 按位于 运算 if (shapeFlag & ShapeFlags.TELEPORT) {解释:如果shapFlag本身值为8,type为1的话,那么转换为二进制(js都是32位)那就是 shapFlag:00000000 00000000 00000000 00001000 …...
MySQL数据库干货_09—— MySQL中的外键约束(Foreign Key)
外键约束(Foreign Key) 添加外键约束 使用DDL语句添加外键约束 ALTER TABLE 表名 ADD CONSTRAINT 约束名 FOREIGN KEY( 列 名 ) REFERENCES 参照的表名(参照的列名);示例一: 创建 departments 表包含 department_id 、department_name ,location_id。…...

springboot配置https
SSL : secure socket layer 是一种加密协议,SSL主要用于保护数据在 客户端和服务器之间的传输,,防止未经授权的访问和窃取敏感信息 在腾讯云申请ssl证书 申请了之后在我的域名中,,解析 解析了之后&…...

java - IDEA IDE - 设置字符串断点
文章目录 java - IDEA IDE - 设置字符串断点概述笔记END java - IDEA IDE - 设置字符串断点 概述 IDE环境为IDEA2022.3 在看一段序列化的代码, 想找出报错抛异常那个点, 理解一下代码实现. 因为序列化代码实现在第三方jar包中, 改不了(只读的). 根本数不清第几次才会开始报…...

【图像分类】基于计算机视觉的坑洼道路检测和识别(ResNet网络,附代码和数据集)
写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。(专栏订阅用户订阅专栏后免费提供数据集和源码一份,超级VIP用户不在服务范围之内,不想订阅专栏的兄弟们可以私信…...
关于readline方法使用的一个中文乱码引发的思考
故事起源于这段代码,我想给一个本地地址然后去读取文件内容,然后使用了reader.readLine();方法,但是本地没有任何报错,但是线上中文乱码导致直接报错了。 BufferedReader reader;try {reader new BufferedReader(new FileReader(…...

BUUCTF 神秘龙卷风 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 神秘龙卷风转转转,科学家用四位数字为它命名,但是发现解密后居然是一串外星人代码!!好可怕! 密文: 下载附件,解压得到一个.rar压缩…...

【JavaEE初阶】 认识文件与Java中操作文件
文章目录 🌴认识文件🚩树型结构组织和目录🚩文件路径(Path)🚩知识扩展 🎍Java 中操作文件🚩File 概述📌属性📌构造方法📌方法 🚩File使…...

数据结构───链表
花费一个周时间学完了链表(的一部分),简单总结一下。 链表的学习离不开画图,将其抽象成一种逻辑模型,可以减少思考时间,方便理解。 链表大致分为8种结构,自己学习并实现了两种结构,也…...
SQLAlchemy删除所有重复的用户|Counter类运用
Python标准库中的collections模块中的Counter类。Counter类用于计算可迭代对象中元素的出现次数,并以字典的形式返回结果,其中键是元素,值是该元素的出现次数。 for name, count in Counter(names).items() 是一个循环语句,它用于…...

Lec11 Thread switching (Robert)
线程的概念 线程就是单个串行执行代码的单元,它只占用一个CPU并且以普通的方式一个接一个的执行指令。 线程还具有状态,我们可以随时保存线程的状态并暂停线程的运行,并在之后通过恢复状态来恢复线程的运行。 程序计数器(Progr…...

前端的简单介绍
前端核心的分析 CSS语法不够强大,比如无法嵌套书写,倒是模块化开发中需要书写很多重复的选择器 没有变量和合理的样式复用机制,使逻辑上相关的属性值必须字面量的心事重复的输出,导致难以维护 CSS预处理器,减少代码的笨重&#…...

云服务器 centos 部署 code-server 并配置 c/c++ 环境
将你的云服务器改为 centos 8 为什么要将云服务器的操作系统改成 centos 8 呢?原因就是 centos 7 里面的配置满足不了 code-server 的需求。如果你使用的是 centos 7 那么就需要你升级一些东西,这个过程比较麻烦。我在 centos 7 上面运行 code-server 的…...
Ubuntu 22.04 安装 Terraform
Ubuntu 22.04 安装 Terraform 安装 Terraform 安装 Terraform sudo apt updatesudo apt install software-properties-common gnupg2 curlcurl https://apt.releases.hashicorp.com/gpg | gpg --dearmor > hashicorp.gpgsudo install -o root -g root -m 644 hashicorp.gpg…...

MLF - 麻辣粉
MLF全称中期借贷便利(Medium-term lending Facility),理解为央行向商业银行、政策银行发放的贷款,但需要符合一定要求才可向央行申请。银行通过MLF向央行借款的时候,需要提供担保品。一般为国债、央行票据、政策性金融债、地方债、…...

Flutter三棵树的创建流程
一、Flutter常见的家族成员 Widget常见的家族成员 Element常见的家族成员 Render常见的家族成员 二、示例代码对应的Flutter Inspector树 示例代码:MyApp->MyHomePage->ErrorWidget,包含了StatelessWidget、StatefulWidget、LeafRenderObjectWid…...
思维训练第二课 独立主格
系列文章目录 文章目录 系列文章目录前言一、独立主格特点 二、独立主格的构成1.名词/人称代词主格现在分词2. 名词/人称代词主格过去分词3. 名词/人称代词主格形容词/副词4. 名词/人称代词主格不定式5. 名词/人称代词主格介词短语6.介词复合宾语 三、独立主格结构的句法功能1、…...

一致性哈希揭秘,深入解析其工作原理
前言 在进行一致性哈希介绍前,先思考2个问题: 什么是Hash一致性Hash和Hash的关系是什么 对于第一个问题Hash的定义 Hash也成散列,基本原理就是把任意长度的输入,通过hash算法变成固定长度的输出。 对于第二个问题,…...

前端环境的安装 Node npm yarn
一 node npm 1.下载NodeJS安装包 下载地址:Download | Node.js 2.开始安装 打开安装包后,一直Next即可。当然,建议还是修改一下安装位置,NodeJS默认安装位置为 C:\Program Files 3.验证是否安装成功 打开DOS命令界面&#…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...