操作系统:文件IO

news/2024/5/14 10:32:00/文章来源:https://blog.csdn.net/wsl_longwudi/article/details/127445606

文章目录

  • 文件描述符
    • 文件描述符池
  • 基本文件操作
    • open
      • open返回文件描述符的规则
      • open的文件描述符与fopen的文件指针
    • close
    • write
    • read
    • lseek
    • fcntl
  • 共享文件操作
    • 同一进程,多次open同一文件
    • 多个进程,多次open同一文件
    • dup
    • dup2
    • 利用dup、dup2实现重定位
  • 高级文件IO
    • 非阻塞IO
      • 如何实现非阻塞读
    • 异步IO

文件描述符

文件描述符是一个非负整数,指向打开的文件。

文件关闭后被文件使用的描述符会被释放,等着下一次open时,被重复利用。

文件描述符池

每个程序运行起来后,就是一个进程,系统会给每个进程分配01˜0230\~102301˜023的描述符范围,也就是说每个进程打开文件时,open所返回的文件描述符,是在01˜0230\~102301˜023范围中的某个数字。01˜0230\~102301˜023这个范围,其实就是文件描述符池。

1023这个上限可不可以改?

可以,但是没有必要,也不会介绍如何去改,因为一个进程基本不可能出现,同时打开1023个文件的情况,文件描述符的数量百分百够用。

进程使用的文件以文件描述符表的形式存放在进程控制块(PCB)中

在这里插入图片描述

  • i节点信息就是文件的权限属性等信息
  • 函数指针
    read、write等操作文件时,会根据底层具体情况的不同,调用不同的函数来实现读写,所以在v节点里面保存了这些不同函数的函数指针,方便调用。

基本文件操作

open

#include <fcntl.h>
int open(const char *pathname,int flags[,mode_t mode]);//open and possibly create a file

如果没有mode参数,只能打开存在的文件,否则会报错;如果有mode参数,就会按照mode指定的文件权限创建文件。

返回:打开成功返回文件操作符,否则返回-1并设置errno

参数:

  • flags

    以下三个选项必选其中之一,且是互斥的

    • O_RDONLY :Open for reading only.

    • O_WRONLY:Open for writing only.

    • O_RDWR:Open for reading and writing. The result is undefined if this flag is applied to a FIFO.

    以下是可选组合选项,通过|逻辑或组合

    • O_CREAT:若欲打开的文件不存在则自动建立该文件.

    • O_EXCL:如果O_EXCL与O_CREAT 被同时设置, 此指令会去检查文件是否存在,文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败.

    • O_NOCTTY:如果欲打开的文件为终端机设备时, 则不会将该终端设备当成进程控制终端机.

    • O_TRUNC:若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.

    • O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面.

    • O_NONBLOCK:以非阻塞的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中.
      如果没有设置O_NONBLOCK:

      • 以只读模式open会阻塞直到有进程open该文件for write
      • 以只写模式open会阻塞知道有进程open该文件for read
      • 只有当设备可用时才会返回

      如果设置了O_NONBLOCK:

      • 当以只读或只写模式打开一个FIFO时,只读模式的open函数会立即返回,只写模式的open函数会返回错误如果当前无进程has the file open for reading
    • O_NDELAY 同O_NONBLOCK.

    • O_SYNC 以同步的方式打开文件.

    • O_NOFOLLOW:如果参数pathname 所指的文件为一符号连接, 则会令打开文件失败.

    • O_DIRECTORY:如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败。

  • 可选参数mode,只有在创建新文件时才会生效

    • S_IRWXU,00700 权限, 代表该文件所有者具有可读、可写及可执行的权限.
    • S_IRUSR 或S_IREAD, 00400 权限, 代表该文件所有者具有可读取的权限.
    • S_IWUSR 或S_IWRITE, 00200 权限, 代表该文件所有者具有可写入的权限.
    • S_IXUSR 或S_IEXEC, 00100 权限, 代表该文件所有者具有可执行的权限.
    • S_IRWXG,00070 权限, 代表该文件用户组具有可读、可写及可执行的权限.
    • S_IRGRP,00040 权限, 代表该文件用户组具有可读的权限.
    • S_IWGRP,00020 权限, 代表该文件用户组具有可写入的权限.
    • S_IXGRP,00010 权限, 代表该文件用户组具有可执行的权限.
    • S_IRWXO,00007 权限, 代表其他用户具有可读、可写及可执行的权限.
    • S_IROTH,00004 权限, 代表其他用户具有可读的权限
    • S_IWOTH,00002 权限, 代表其他用户具有可写入的权限.
    • S_IXOTH,00001 权限, 代表其他用户具有可执行的权限.

open返回文件描述符的规则

open返回文件描述符池中当前最小的没有用到的那一个。
进程一运行起来,0/1/2默认就被使用了,最小没被用的是3,所以返回3。
如果又打开一个文件,最小没被用的就应该是4,所以open返回的应该是4。

  1. 程序开始运行时,有三个文件被自动打开了,打开时分别使用了这三个文件描述符。
  2. 依次打开的三个文件分别是/dev/stdin,/dev/stdout,/dev/stderr。
    • /dev/stdin:标准输入文件
      • 程序开始运行时,默认会调用open (“/dev/stdin”,O_RDONLY)将其打开,返回的文件描述符是0
      • 使用0这个文件描述符,可以读取从键盘输入的数据
        简单理解就是,/dev/stdin这个文件代表了键盘。
    • /dev/ stdout:标准输出文件
      • 程序开始运行时,默认open(“/dev/stdout”,O_WRONLY)将其打开,返回的文件描述符是1。先打开的是/dev/stdin,把最小的0用了,剩下最小没用的是1,因此返回的肯定是1。
      • 通过1这个文件描述符,可以将数据写(打印)到屏幕上显示
        简单理解就是,/dev/ stdout这个文件代表了显示器。
      • 人只看得懂字符,所以所有输出到屏幕显示的,都必须转成字符。
        所以我们输出时,输出的必须是文字编码,显示时会自动将文字编码翻译为字符图形。所以我们输出65时,65解读为A字符的AsCII编码,编码被翻译后的图形自然就是A
    • /dev/stderr:标准错误输出文件
      • 默认open(“/dev/stderr”,O_WRONLY)将其打开,返回的文件描述符是2
      • 通过2这个文件描述符,可以将报错信息写(打印)到屏幕上显示
      • write(2,buf,sizeof(buf))将buf中的数据写道屏幕上,
        数据中转的过程是:write应用缓存buf ->open /dev/stderr时开辟的内核缓存->显示器驱动程序的缓存->显示器
      • 1和2啥区别?
        使用这两个文件描述符,都能够把文字信息打印到屏幕。如果仅仅是站在打印显示的角度,其实用哪一个文件描述符都能办到。

open的文件描述符与fopen的文件指针

  1. open: Linux 的系统函数(文件io函数)
    open成功后,返回的文件描述符,指向了打开的文件。

  2. fopen:c库的标准io函数

    #include <stdio.h>
    FILE* fopen (const char *path,const char *mpde);
    

    fopen成功后,返回的是FILE*的文件指针,指向了打开的文件。

  3. 对于Linux的c库来说,fopen这个c库函数,最终其实还是open函数来打开文件的
    fopen只是对open这个函数做了二次封装。

close

#include <unistd.h>
int close(int fd);//close a  file descriptor
  1. 参数

    • fd:指向打开文件的文件描述符
  2. 返回值
    调用成功:返回0
    调用失败:返回-1,并给errno自动设置错误号

write

#include <unistd.h>
ssize_t write(int fd,const void *buf,size_t count);//write to a file descriptor
  1. 功能:向fd所指向的文件写入数据。

  2. 参数

    • fd:指向打开文件的文件描述符
    • buf:保存数据的缓存空间的起始地址
    • count:从起始地址开始算起,把缓存中count个字符,写入fd指向的文件

    数据中转的过程:
    应用缓存(buf)—>open打开文件时开辟的内核缓存—>驱动程序的缓存—>块设备上的文件

  3. 返回值
    调用成功:返回所写的字符个数
    调用失败:返回-1,并给errno自动设置错误号

直接写字符串常量时,字符串常量被保存(缓存)在了常量区,编译器在翻译如下这句话时,write (fd, “hello world” , strlen ( “hello world”) )会直接将"hello world"翻译为"hello world"所存放空间的起始地址(也就是h所在字节的地址),换句话说,直接使用使用字符串常量时,字符串常量代表的其实是一个起始地址。

read

#include <unistd.h>
ssize_t read(int fd,const void *buf,size_t count);//read from a file descriptor
  1. 功能:从fd指向的文件中,将数据读到应用缓存buf中

  2. 参数

    • fd:指向打开的文件
    • buf:读取到数据后,用于存放数据的应用缓存的起始地址
    • count:缓存大小(字节数)

    数据中转的过程:应用缓存(buf)<—open打开文件时开辟的内核缓存<—驱动程序的缓存<—块设备上的文件

  3. 返回值
    1)成功:返回读取到的字符的个数
    2)失败:返回-1,并自动将错误号设置给errno。

lseek

#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
  1. 功能
    调整读写的位置,就像在纸上写字时,挪动笔尖所指位置是一样的。
    c库的标准io函数里面有一个fseek函数,也是用于调整读写位置的,fseek就是对lseek系统函数封装后实现的。

  2. 返回值

    • 调用成功:返回当前读写位置相对于文件开始位置的偏移量(字节)。
      可以使用lseek函数获取文件的大小,将文件读写的位置移动到最末尾,然后获取返回值,这个返回值就是文件头与文件尾之间的字节数,也就是文件大小。
    • 调用失败:返回-1,并给errno设置错误号。
  3. 参数:

    • fd:文件描述符
    • whence:粗定位
      • SEEK_SET :调到文件起始位置
      • SEEK_CUR:调到文件当前读写位置
      • SEEK_END:调到文件末尾
    • offset:精定位,微调位置(byte),负数向前,正数向后

fcntl

#include <unistd.h>                                                           
#include <fcntl.h>                                                                   
int fcntl(int fd, int cmd, ... /* arg */ ); 
  1. 功能
    fcntl函数其实是File Control的缩写,可以通过fcntl设置、或者修改已打开文件的某些性质。

  2. 返回值
    调用成功:返回值视具体参数而定
    调用失败:返回-1,并把错误号设置给errno。

  3. 参数

    • fd:指向打开文件的文件描述符

    • /* arg */是多余的参数如果没有用到就写0

    • cmd:控制命令,通过指定不同的宏来修改fd所指向文件的性质。

      • F_DUPFD
        复制描述符,可用来模拟dup和dup2,后面会有例子对此用法进行说明。
        返回值:返回复制后的新文件描述符

        #include <unistd.h>
        fd=open(FILE_NAME,O_RDWR);
        //模拟dup2(fd,1);
        close(1);
        fd1=fcntl(fd,F_DUPFD,1);
        
      • F_GETFL、F_SETFL
        获取、设置文件状态标志,比如在open时没有指定O_APPEND,可以使用fcntl函数来补设。
        返回值:返回文件的状态标志

        什么时候需要fcntl来补设?
        当文件描述符不是你自己open得到,而是调用别人给的函数,别人的函数去open某个文件,然后再将文件描述符返回给你用,在这种情况下,我们是没办法去修改被人的函数,在他调用的open函数里补加文件状态标志。此时就可以使用fcntl来补设了,使用fcntl补设时,你只需要知道文件描述符即可。

      • FGETFD、FSETFD

      • F_GETOWN、F_SETOWN
        获取或设置文件描述符所属进程,如fcntl(mousefd,F_SETOWN,getpid());

      • F_GETLK或F_SETLK或F_SETLKW

共享文件操作

有两种情况:

  • 同一进程共享操作相同的文件
  • 多个进程之间,共享操作相同文件

同一进程,多次open同一文件

  • 在进程内多次open打开同一文件时,文件描述符是不同的。在同一进程里面,一旦某个文件描述符被用了,在close释放之前,别人不可能使用,所以指向同一文件的描述符不可能相同。

  • 如果不用O_APPEND选项,open打开同一文件的多个文件描述符同时写数据时会相互覆盖:
    不同文件描述符对应不同的文件表,文件表内的文件偏移量也是独立的,一个文件描述符写操作不会影响另一个文件描述符对应的文件偏移量不变,它们写的位置是重叠的,就会相互覆盖。

  • 指定O_APPEND参数即可解决覆盖问题
    必须每个open都要指定,有一个不指定就会覆盖,就先过马路一样,都要准守交通规则才能安全,开车的和行人,只要有一个不准守都会出事。
    共享操作的文件描述符对应同一个V节点,V节点中的文件长度信息是大家共享的,当文件被写入数据后,文件长度就会被更新,都指定O_APPEND后,使用不同的文件描述符写数据时,都会先使用文件长度更新自己的文件位移量,保证每次都是在文件的最末尾写数据,就不会出现相互覆盖的情况。

在这里插入图片描述

多个进程,多次open同一文件

同单进程文件共享相同,同样因为各自有独立的文件偏移量存在覆盖问题,解决方法同样为加O_APPEND标志。

在这里插入图片描述

dup

#include <unistd.h>
int dup(int oldfd);
  1. 功能
    复制某个已经打开的文件描述符,得到一个新的描述符,这个新的描述符,也指向被复制描述符所指向的文件。至于需要用到的新描述符,dup会使用描述符池(0~1023)中当前最小没用的那一个。
  2. 返回值
    • 成功:返回复制后的新文件描述符
    • 失败:返回-1,并且errno被设置。
  3. 参数
    oldfd:被复制的已经存在的文件描述符

dup2

#include <unistd.h>
int dup2(int oldfd,int newfd);
  1. 功能

    功能同dup,只不过在dup2里面,我们可以自己指定新文件描述符。如果这个新文件描述符已经被打开了,dup2会把它给关闭后,再使用。
    dup2和dup的不同之处在于:
    dup:自己到文件描述符池中找新文件描述符dup2:我们可以自己指定新文件描述符

  2. 返回值

    • 成功:返回复制后的新文件描述符
    • 失败:返回-1,并且errno被设置。
  3. 参数
    oldfd:被复制的已经存在的文件描述符
    newfd:新的文件描述符

利用dup、dup2实现重定位

#include <unistd.h>
int fd1=0,fd2=0;
fd1=open(FILE_NAME,O_RDWR|O_TRUNC);close(1);
fd2=dup(fd1);
//或
dup2(fd,1);

函数中的文件描述符值写死了,无法修改为新的描述符,但是你又希望该函数,把数据输出到其它文件中,此时就可以使用dup、dup2对该函数中的文件描述符,进行重定位,指向新的文件,函数就会将数据输出到这个新文件。

linux命令>就是dup、dup2的典型应用

高级文件IO

非阻塞IO

读键盘、鼠标是阻塞的;读普通文件时,如果读到了数据就成功返回,如果没有读到数据返回0,总之不会阻塞。

可以将阻塞的读改为非阻塞的读,非阻塞读的意思就是说,如果有数据就成功读到,如果没有读到数据就出错返回,而不是阻塞。

如何实现非阻塞读

  1. 打开文件时指定O_NONBLOCK状态标志

    fd=open("/dev/input/mouse0",O_RDONY|O_NONBLOCK);
    
  2. 通过fcntl函数指定O_NONBLOCK来实现

    • 情况1:当文件已经被open打开了,但是open是并没有指定你要的文件状态标志,而你又想去修改open的参数,此时就是可以使用fcntl来补设。
    • 情况2:没办法在open指定,你手里只有一个文件描述符fd,此时就使用fcntl来补设
      比如无名管道,无名管道连名字都没有,没办法使用open函数,无名管道是使用pipe函数来返回文件描述符的,如果过你想非阻塞的读无名管道的话,是没有办法通过open来指定O_NONBLOCK的,此时就需要使用fcntl来重设或者补设。

异步IO

异步IO类似中断,读鼠标键盘 没有数据时进程干自己的事,有数据之后底层驱动给进程发一个SIGIO信号,通知进程数据准备好了,进程来处理数据。

不过使用异步IO有两个前提,

  1. 底层驱动必须要有相应的发送SIGIO信号的代码,只有这样当底层数据准备好后,底层才会发送SIGIO信号给进程。
    我们之所以可以对鼠标设置异步IO,是因为人家在实现鼠标驱动时,有写发送SIGIO信号的代码,如果驱动程序是我们自己写的,发送SIGIO的代码就需要我们自己来写。
  2. 应用层必须进行相应的异步IO的设置,否者无法使用异步IO
    应用层进行异步IO设置时,使用的也是fcntl函数。

使用异步IO时应用层的设置步骤:

  • 调用signal函数对SIGIO信号设置捕获函数
    在捕获函数里面实现读操作,比如读鼠标。

  • 使用fcntl函数,将接收SIGIO信号的进程设置为当前进程
    如果不设置的,底层驱动并不知道将SIGIO信号发送给哪一个进程

    fcntl(mousefd,F_SETOWN,getpid());
    
  • 使用fcntl函数,对文件描述符增设O_ASYNC的状态标志,让fd支持异步IO

    mousefd = open("/dev/input/mouse1",O_RDONLY);
    flag = fcntl(mouse_fd,F_GETFL);
    flag |= O_ASYNC;//补设O_ASYNC
    fcntl(mouse_fd,F_SETFL,flag) ;
    

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

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

相关文章

【网络安全-键盘监视】学会以后去捉弄舍友,看他有了什么不可告人的秘密

&#x1f343;博主昵称&#xff1a;一拳必胜客 博主主页面链接&#xff1a;博主主页传送门 博主专栏页面连接&#xff1a;专栏传送门–计算机考研 &#x1f351;创作初心&#xff1a;本博客的初心是每天分享记录自己学习的脚步&#xff0c;和各位技术友探讨交流&#xff0c;同时…

通过jmap、jstack分析问题,以及分析方法

一、问题 多批次导入任务&#xff0c;会出现异步线程停止工作的情况&#xff0c;后续无论导入多少任务&#xff0c;异步线程都不会执行&#xff0c;只有重启能解决。 二、工具使用 进入jdk的bin目录&#xff1a; cd /beeb/ap/uip/jdk1.8.0_231/bin 2.1 拉取jstack日志&…

setContentView源码解析

一、引言 本文将解析activity加载布局文件的setContentView源码&#xff0c;由于会涉及到部分activity的启动流程&#xff0c;这里附上一张activity启动流程图&#xff1a; 关于 setContentView 源码分两种情况&#xff0c;因为我们的 activity 有两个&#xff1a; 一种是继…

halcon脚本-边缘及骨架的识别【附源码】

文章目录前言一、原图1.边缘图2.骨架图二、实现思路1.边缘图2.骨架图三、halcon脚本实现1.边缘图2.骨架图四、实现效果1.边缘图2.骨架图前言 本文实现基于图像进行边缘或者骨架的识别&#xff0c;可实现让机器人画画 一、原图 1.边缘图 2.骨架图 二、实现思路 1.边缘图 提取…

【阅读】一周翻过《构建之法》,笔记整理

文章目录&#x1f6a9; 前言&#x1f966; 阅读笔记&#x1f33e; 结语&#x1f6a9; 前言 我的阅读方式 我拿到这本书挺久了&#xff0c;之前已经零散地看过一部分&#xff0c;最近一周集中地花了一些时间&#xff0c;将整本书看过了一遍。看得比较粗略&#xff0c;正如“好读…

怎么管理员工混工时的现象?

如果员工存在混工时&#xff0c;这表明公司的管理存在漏洞。让懒散的员工认为自己可以混日子&#xff0c;让没有绩效考核的员工默认可以混日子&#xff0c;同时让对公司感到失望的员工可以完全躺平等待被公司解雇。 工时管理一直是企业需求与痛点。特别是在疫情时期&#xff0c…

华为云数据库GaussDB 为企业核心数据运行提供优质保障

华为云数据库GaussDB 为企业核心数据运行提供优质保障 在网络信息科学技术不断发展的今天&#xff0c;海量存储信息数据中大量的存储资源被浪费&#xff1f;你有没有遇见信息数据备份恢复很慢的情况&#xff1f;让人特别的烦躁&#xff0c;特别是企业遇见了这些情况&#xff0c…

JDBC工具类和JDBC登录案例

JDBC工具类: 抽取JDBC工具类:JDBCUtils 目的:简化书写 分析∶ 1.注册驱动也抽取 2.抽取一个方法获取连接对象 3.抽取一个方法释放资源 代码实现:/*** JDBC工具类*/ public class JDBCUtils {private static String url;private static String user;private static Strin…

Cadence Allegro PCB设计88问解析(十一) 之 Allegro中文件自动保存时间设置

一个学习信号完整性的layout工程师 大家在设计图纸或者编辑文档时&#xff0c;最常点击的应该就是保存图标了。谁也不想因为软件闪退、电脑断电等情况&#xff0c;我们的劳动成果就白白的消失了。在我们用Allegro进行PCB设计&#xff0c;就会有一个自动保存的功能&#xff0c;每…

数字化转型大潮下,企业如何做好绩效管理?

久其EPM白皮书的正式发布&#xff0c;为企业财务的数字化转型实践提供了极具价值的参考。企业绩效管理&#xff08;EPM&#xff09;成为行业热点对于一家企业来说&#xff0c;做好绩效管理究竟有多重要&#xff1f;对于这个问题&#xff0c;全球商界传奇人物、GE前CEO杰克韦尔奇…

事件对象的介绍

● 什么是事件对象&#xff1f;就是当你触发一个事件以后&#xff0c;对该事件的一些描述信息 ● 例如&#xff1a; ○ 你触发一个点击事件时&#xff0c;你点了哪个位置&#xff0c;坐标多少&#xff0c;都在事件对象的属性中体现 ○ 你触发一个键盘事件时&#xff0c;你按下…

探索增强型灰狼优化算法

文章目录一、理论基础1、灰狼优化算法2、探索增强型灰狼优化算法&#xff08;1&#xff09;改进的位置更新公式&#xff08;2&#xff09;非线性控制参数策略&#xff08;3&#xff09;EEGWO算法伪代码二、仿真实验与结果分析三、参考文献一、理论基础 1、灰狼优化算法 请参考…

计算机科学与技术是信息文明时代的入口,是数字世界的基石,是人们必须掌握的基本技能之一

从人类科技发展史的角度看&#xff0c;软件工程&#xff08;计算机编程&#xff09;是刚刚开始的信息文明巨大的趋势中的一部份。人类至今经历过三次工业革命。第一次工业革命的代表是蒸汽机&#xff0c;使得人类拥有了强大的动力。第二次工业革命的代表是电力和石油&#xff0…

高数_第6章无穷级数_幂级数之__阿贝尔定理

阿贝尔定理&#xff1a; 如果幂级数 在 点 x x₀(x₀≠0)处收敛&#xff0c; 则对于适合不等式 |x| < |x₀|的一切x, 都有幂级数 在点 x 处绝对收敛&#xff1b; 反之&#xff0c;如果幂级数 在点 x x₀ (x₀≠0)处发散&#xff0c; 则对于适合不等式 |x| >…

使用Code Chart绘制流程图

Code Chart介绍 Code Chart是一个基于 Javascript 的图表和图表工具&#xff0c;它基于 markdown 语法来简化和加速生成流程图的过程&#xff0c;也不止于生成流程图。 工具地址&#xff1a;https://www.iodraw.com/codechart 图形 头部用graph 或flowchart 关键字来声明流程…

Anaconda安装

文章目录1. Anaconda3简介2. Anaconda3下载3. Anaconda3安装1. Anaconda3简介 Anaconda3 是一个用于 Python 科学计算和机器学习的开源工具&#xff0c;它是 Python 的一个科学计算发行版&#xff0c;支持 Linux、macOS 和 Windows 系统&#xff0c;包含 conda 等众多工具包和…

python抓取Prometheus的数据(使用prometheus-api-client库)

python抓取Prometheus的数据(使用prometheus-api-client库) 0、写在前面 我们要想抓取Prometheus的数据,一般想到的就是requests请求,爬虫的方式来抓取,这是可行的,当然,还有一个第三方库直接封装好了,直接用就行,代码也比较少,源码点进去就能看明白,这个库叫promet…

多链世界的“高速公路”:一文读懂跨链协议演进与未来

当我们发现自己正处于另一个“加密货币寒冬”之中——这在很大程度上是由一系列项目破产、监管打击和宏观看跌推动的——但重要的是&#xff0c;我们不要忽视促成下一次牛市的技术突破和将权力下放的精神重新引入大众。 上一个周期的主题之一仍然是行业参与者讨论的最前沿的主…

无网络机器上,win下vscode客户端通过ssh连接linux服务器

目录 参考文献 前言 下载安装VSCode 下载 安装 下载和安装必要的VSCode插件 下载 安装 客户端通过ssh远程连接linux服务器 下载并安装ssh 远程连接linux服务器 参考文献 Windows使用VSCode远程Linux&#xff08;ConteOS&#xff09;开发/调试C/C&#xff08;超详细…

是真是假,AI可根据声音检测是否感染新冠 准确率达89%

据媒体报道&#xff0c;近日&#xff0c;在西班牙巴塞罗那举行的欧洲呼吸学会国际会议上公布的一项研究显示&#xff0c;AI可通过手机应用程序从人们声音中检测出新冠肺炎感染&#xff0c;其准确率达到89%。 新冠肺炎感染通常会影响上呼吸道和声带&#xff0c;导致一个人的声音…