【Linux】基础IO [万字之作]

目录

 一.重谈文件

二.重谈C文件操作

1.操作

1.文件的打开和关闭

2.文件的读写操作

 ​编辑

1.fgetc函数

2.fputc函数

 3.fputs函数

 4.fgets函数

 5.fprintf函数

6.fscanf函数

7.fread函数

8.fwrite函数

三.重谈当前路径

四.系统文件操作接口

 1.Open函数

2.write函数

3.read函数

4.close函数

5.总结


hello,my friend。今天我们要学习的是基础IO部分,主要涉及内存和外设之间的数据交互。接下来,就让我们共同探讨这部分内容吧,那我们就开始吧!

本文章重点:

  • 复习C文件IO相关操作
  • 认识文件相关系统调用接口
  • 认识文件描述符,理解重定向
  • 对比fd和FILE,理解系统调用和库函数的关系
  • 理解文件系统中inode的概念
  • 认识软硬链接,对比区别
  • 认识动态静态库,学会结合gcc选项,制作动静态库

 一.重谈文件

首先,我认为有必要明确一些共识:

  1. 空文件,也要在磁盘中占用空间(即使是空文件,也要有数据存储)。
  2. 文件=内容+属性。
  3. 对文件进行操作=对内容进行操作or对属性进行操作or对内容和数据同时进行操作。
  4. 在任何系统中,标定一个文件,必须使用:文件路径+文件名(唯一性)。
  5. 如果没有指明对应的文件路径,默认是在当前路径下进行文件访问。
  6. 当我们把fopen,fclose,fread,fwrite等接口写完后,代码完成编译,形成二进制可执行程序后,但是没有被运行,文件对应的操作有没有被执行——没有,对文件的操作,本质上是:进程对文件的操作。
  7. 一个文件如果没有被打开,可以直接对该文件进行访问吗?不能,一个文件要被访问,必须得先被打开。打开工作由用户+OS完成。
  8. 是不是所有在磁盘上的文件都被打开了?不是!文件大体分为:a.被打开的文件,b.没有被打开的文件(这部分组成我们的文件系统)。

总结:文件操作的本质:进程和被打开文件之间的关系。

二.重谈C文件操作

C语言有文件操作接口,C++有文件操作接口,jave有文件操作接口,python有文件操作接口。但这些接口差别很大。

文件在哪里——>文件在磁盘——>磁盘属于硬件,由操作系统进行管理——>所有人想访问磁盘都绕不开操作系统——>使用操作系统的接口——>提供文件级别的系统调用接口——>吧冉语言的文件操作接口都可以在Linux下运行——>底层接口是一样的,这是变换的接口中不变的东西。

1.操作

1.文件的打开和关闭

在使用文件之前应该打开文件,使用完之后应该关闭文件

ANSIC规定用fopen来打开文件,用fclose来关闭文件

FILE * fopen ( const char * filename, const char * mode );	//打开文件
int fclose ( FILE * stream );	//关闭文件

注1:当文件打开失败出错时,会返回一个空指针,因此我们一定要在打开文件之后,对文件指针进行有效性检查
注2:对于打开进行更新的文件(包含“+”号的文件),允许输入和输出操作,在写入操作之后的读取操作之前,应刷新(fflush)或重新定位流(fseek,fsetpos,rewind)。流应在读取操作之后的写入操作之前重新定位(fseek、fsetpos、rewind)(只要该操作未到达文件末尾)

实例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* fp = fopen("hello.c", "w");
	if (fp == NULL)
	{
		perror("fopen fail");

	}
	//进行文件相关的读写操作。

	fclose(fp);
}

运行前: 

运行后: 

2.文件的读写操作

如下是C语言文件操作相关函数

 

我们知道:在C语言占位符中:%c表示字符,%s表示字符串。上面的以字符C结尾fgetc和fputc分别便是读取和输入一个字符。以字符Sfgets和fputs分别便是读取和输入字符串。

下面我挑重点讲解几个函数:

1.fgetc函数
int fgetc ( FILE * stream );
  •  返回文件指针当前指向的字符,然后文件指针向后移动一位
  • 如果文件指针位于文件末尾,那么就返回EOF,并为流设置 (feof) 的文件结束指示器
  • 如果文件读取错误,同样返回EOF,但改为设置其错误指示器 (ferror)

实例:从data.txt文件中读取一个字符。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* fp=fopen("data.txt","r");
    if (fp==nullptr)
    {
        perror("fopen fail");
        exit(1);
    }
    char ch=fgetc(fp);
    printf("%c",ch);
    fclose(fp);
    fp=nullptr;
    return 0;
}
2.fputc函数
int fputc ( int character, FILE * stream );
  • 将一个字符写入文件,然后文件指针向后移动一位
  • 如果写入成功,那么返回这个字符的ASCII值
  • 如果发生错误,则返回EOF

实例:创建一个data.txt文件,并写入字符‘a’; 

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* fp=fopen("data.txt","w");
    if (fp==nullptr)
    {
        perror("fopen fail");
        exit(1);
    }
    fputc('a',fp);
    fclose(fp);
    fp=nullptr;
    return 0;
}

运行结果: 

 3.fputs函数
int fputs ( const char * str, FILE * stream );
  • 将str中的字符串输出到流(stream)中,结束符‘\0’不会被写入
  • 如果输出成功,则返回非负值
  • 如果失败,则返回EOF,并设置错误指示器(ferror)

 实例:

将字符串“abcdefg”写入data.txt文件。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* fp=fopen("data.txt","w");
    if (fp==nullptr)
    {
        perror("fopen fail");
        exit(1);
    }
   
    fputs((char*)"abcdefg",fp);
    fclose(fp);
    fp=nullptr;
    return 0;
}

 4.fgets函数
char * fgets ( char * str, int num, FILE * stream );

  • 从流(stream)中读取字符,并以字符串的形式存储到str中,直到读够(num - 1)个字符,或到达换行符,或读到文件尾
  • 换行符‘\n’会使fgets停止读取,但换行符会被函数认为是有效字符,并存入str中
  • 结束符‘\0’会成为第num个字符,添加到str末尾
  • 如果读取成功,则返回str
  • 如果在读取的过程中遇到文件尾,那么就设置 eof 指示器 (feof)
  • 如果没有读到任何字符就遇到文件尾,那么就返回空指针,设置 eof 指示器 (feof),str的内容不会改变
  • 如果读取错误,则设置错误指示器(ferror),同样返回空指针,但str的内容可能会改变

实例:从data.txt中读取所有字符。


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    FILE* fp=fopen("data.txt","r");
    if (fp==nullptr)
    {
        perror("fopen fail");
        exit(1);
    }
    char ret[10];
    memset(ret,0,10);//初始化空间为0;
    fgets(ret,6,fp);
    printf("%s",ret);
    fclose(fp);
    fp=nullptr;
    return 0;
}

 5.fprintf函数
int fprintf ( FILE * stream, const char * format, ... );

  • 以格式化的形式向流(stream)中输出数据

  • 成功后,将返回写入的字符总数

  • 如果发生写入错误,则设置错误指示器(ferror)并返回负数。

例如:

将数字123和字符串“abcdef”写入文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    int num=123;
    char *arr="abcdef";
    FILE *fp=fopen("data.txt","w");
    if(fp==nullptr)
    {
        perror("fopen fail");

    }
    fprintf(fp,"%d:%s",num,arr);
    fclose(fp);
    fp=nullptr;
    return 0;
}

6.fscanf函数
int fscanf ( FILE * stream, const char * format, ... );
  • 格式化的形式从流(stream)中读取数据
  • 成功后,该函数返回成功填充的参数列表的项数。此计数可以与预期的项目数匹配,也可以由于匹配失败、读取错误或文件末尾的到达而减少(甚至为零)。
  • 如果发生读取错误或在读取时到达文件末尾,则会设置正确的指示器(feof 或 ferror)。并且,如果在成功读取任何数据之前发生任一情况,则返回 EOF。

 实例:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    FILE *fp=fopen("data.txt","r");
    if(fp==nullptr)
    {
        perror("fopen fail");

    }
    int num=0;
    char arr[10]={0};
    fscanf(fp,"%d:%s",&num,arr);
    printf("%d:%s\n",num,arr);
    fclose(fp);
    fp=nullptr;
    return 0;
}

7.fread函数
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

以二进制的形式从流中读取count个元素,每个元素的大小为size字节,并将它们存储在 ptr 指定的内存块中。

返回成功读取的元素总数。

如果此数字与 count 参数不同,则表示读取时发生读取错误或到达文件末尾。在这两种情况下,都会设置正确的指标,可以分别用 ferror 和 feof 进行检查。

如果size或count为零,则该函数返回零,并且流状态和 ptr 指向的内容保持不变。

例如:读取文件中的字符串“1200”

int main()
{
	FILE* fp = fopen("data.txt", "rb");
	if (NULL == fp)
	{
		perror("fopen");
		return 1;
	}

	int str[10] = {0};

	int ret = fread(str, sizeof(int), 1, fp);
	for (int i = 0; i < 10; i++)
		printf("%d ", str[i]);

	printf("\nret = %d\n", ret);
    
    fclose(fp);
	fp = NULL;

	return;
}
8.fwrite函数
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

以二进制的形式将ptr存储的数据写入流中,一共写入count个元素,每个元素的大小为size字节。

返回成功写入的元素总数。

如果此数字与 count 参数不同,则写入错误阻止函数完成。在这种情况下,将为流设置错误指示器(ferror)。

如果size或count为零,则该函数返回零,错误指示器保持不变。

例如:

向文件中写入字符串“abcdef”

#include<stdio.h>

int main()
{
	FILE* fp = fopen("data.txt", "wb");
	if (NULL == fp)
	{
		perror("fopen");
		return 1;
	}

	char str[] = "abcdef";

	int ret = fwrite(str, sizeof(char), strlen(str), fp);
	printf("%d\n", ret);

	fclose(fp);
	fp = NULL;

	return 0;
}

三.重谈当前路径

我们在用fopen以写的方式打开一个文件,如果文件不存在,系统会在当前路径下创建该文件,但为什么创建文件是在当前路径下创建呢?操作系统怎么找到当前路径的呢?

运行起该进程,然后查询到pid,在系统proc文件夹下查找。

其中,有两个非常显眼:

  1. exe表示当前运行程序所处的路径。
  2. cwd表示当前运行程序的工作目录。这个目录只属于当前运行的进程。这个工作目录我们可以使用系统中的 chdir进行修改。

来看实例:

#include<stdio.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
    chdir("/home/user/exercise");//修改该进程的工作目录。
    FILE* fp=fopen("log.txt","w");
    while(1)
    {
        printf("hello world\n");
        sleep(1);
    }
}

这样,我们就把进程的工作目录更改到了/home/user/exercise下。

运行一下:

我们可以看到:文件就在我们修改后的工作目录下创建好了。 

四.系统文件操作接口

 我们除了使用C语言函数或者其他语言函数对文件进行相关的操作,我们也可以调用系统文件操作接口来实现对文件的操作,且系统接口更加接近底层,语言层面的函数都是对系统接口的封装。

 1.open函数

C语言的fopen函数底层就是依据open实现的,其为Linux的系统调用,函数原型为:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

 头文件:

  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>

参数

  • pathname:要进行操作的文件所在路径和文件名,如果只有文件名,表示此文件在当前目录下;当文件不存在时,也要在当前目录下创建。
  • flags:表示要对文件的操作类型,常见的操作类型有:
  • mode:表示:文件不存在时,创建文件的默认权限。当文件存在,这个参数不需要传。

 对flag的进一步理解:

 flag的中文名称是旗帜(标记位)的意思。这里的采用比特位的数组进行标记,并用位运算符进行运算,得到对文件的操作类型。为了更好的理解,我们来看这段代码:

#include <stdio.h>
#include <stdlib.h>

#define ONE (1 << 0)
#define TOW (1 << 1)
#define THREE (1 << 2)
#define FOUR (1 << 3)

void show(int flag)
{
    if (flag & ONE)
        printf("ONE\n");
    if (flag & TOW)
        printf("TOW\n");
    if (flag & THREE)
        printf("THREE\n");
    if (flag & FOUR)
        printf("FOUR\n");
}
int main()
{
    show(ONE);
    printf("--------------------------------------\n");
    show(ONE | TOW);
    printf("--------------------------------------\n");
    show(ONE | TOW | THREE);
    printf("--------------------------------------\n");
    show(ONE | THREE);
}

我们可以 使用或运算 来做出 不同的行为,同样,open接口的flags参数也是如此使用方式,例如,我们以 使用open模拟fopen函数的 ‘w’ 行为

include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#define MY_ENY "log.txt"
int main()
{
    int n = open("MY_ENY", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    assert(n > -1);

    // 进行相关的写操作。
    close(n);
    return 0;
    
}

 我们真的使用open函数模仿除了fopen的‘w’行为,但是,仔细观察:我们发现创建的文件权限列表为0664,但是我们在open参数列表中传入的是:0666。这其中是权限掩码的原因(umask)。我们系统设定的权限掩码为0002,真正的权限列表为:umask&mode。当然,这个掩码也是可以修改的:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
int main()
{
    umask(0);//修改权限掩码为0000;
    int n = open("MY_ENY", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    assert(n > -1);

    // 进行相关的写操作。
    close(n);
    return 0;

}

 结果不出所料:

2.write函数

 函数原型

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

参数

  •  fd,就是调用open的返回值,也就是文件描述符(这个之后再说)。
  • buf:需要写入文件的字符串的起始地址。
  • count,写入文件的字符串的长度。
  • 其中第三个参数需要注意,传入的字符串长度是不算 \0 的,因为这是系统调用接口,并非C语言。 

实例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include<string.h>
int main()
{
    int cnt=5;
    umask(0);//修改权限掩码为0000;
    int n = open("MY_ENY", O_WRONLY | O_CREAT , 0666);
    assert(n > -1);
    char *arr="abcdefg";
    char outBUffer[1024]={0};
    while(cnt--)
    {
        sprintf(outBUffer,"%s:%d\n",arr,cnt);
        ssize_t m=write(n,outBUffer,strlen(outBUffer));
        // 进行相关的写操作。
    }
    
    close(n);
    return 0;

}

运行一下:

结果不出意料。

接着,我们修改一下代码:修改一下要写入的数据。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include<string.h>
int main()
{
    int cnt=5;
    umask(0);//修改权限掩码为0000;
    int n = open("MY_ENY", O_WRONLY | O_CREAT ,0666);
    assert(n > -1);
    char *arr="www";
    char outBUffer[1024]={0};
    while(cnt--)
    {
        sprintf(outBUffer,"%s:%d\n",arr,cnt);
        ssize_t m=write(n,outBUffer,strlen(outBUffer));
        // 进行相关的写操作。
    }
    
    close(n);
    return 0;

}

运行一下:我们发现结果并不是我们预料的把之前的内容清空,然后再重新写入。 

 

这是因为我们少传入了一个flag选项O_TRUNC,这个选项的作用就是在写入之前,清空文件里边的所有内容。

我们传入这个flag选项观察一下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include<string.h>
int main()
{
    int cnt=5;
    umask(0);//修改权限掩码为0000;
    int n = open("MY_ENY", O_WRONLY | O_CREAT|O_TRUNC ,0666);
    assert(n > -1);
    char *arr="www";
    char outBUffer[1024]={0};
    while(cnt--)
    {
        sprintf(outBUffer,"%s:%d\n",arr,cnt);
        ssize_t m=write(n,outBUffer,strlen(outBUffer));
        // 进行相关的写操作。
    }
    
    close(n);
    return 0;

}

如此,一切都显得合理合规了。

3.read函数

read函数是Linux下的一个系统调用接口,C语言的fread函数的底层就是read。作用为从一个特定的文件流中读取内容。

函数原型:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

参数:

  • fd是一个文件描述符,就是调用open函数时的返回值。
  • buf:表示从文件中读取的内容读到buf里。
  • count:表示读取的元素个数。

返回值 

如果读取成功的话,返回读取到的元素的个数。

实例:

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
int main()
{
    int cnt=5;
    //umask(0);//修改权限掩码为0000;
    //int n = open("MY_ENY", O_WRONLY | O_CREAT|O_TRUNC ,0666);
    //assert(n > -1);
    int n=open("MY_ENY",O_RDONLY);//读文件时,文件一定存在。
    char arr[1024]={0};//先定义一个缓冲区,用于存放读取到的内容。
    ssize_t m=read(n,arr,sizeof(arr));
    assert(m>0);
    arr[m]='\0';//使用C语言的方式对内容进行打印,字符串以'\0'结尾,\0=0=nullptr;:wq

    printf("%s",arr);
    
    close(n);
    return 0;

}

运行一下:

结果就出现了。

4.close函数

close函数也是Linux下的一个系统调用接口,C语言的fclose底层就是close。

参数

fd就是调用open时的返回值,本质是第一个文件描述符。

5.总结

c语言库函数底层调用操作系统接口,然后系统调用接口把结果返回给C语言库函数。
 

写到最后,因作者水平有限,文中难免会有错误,请各位指正!!

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

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

相关文章

hot100 -- 栈

目录 &#x1f6a9;有效的括号 &#x1f33c;最小栈 AC 栈 AC 链表 &#x1f33c;字符串解码 &#x1f43b;每日温度 &#x1f352;柱状图中的最大矩形 解释 AC 单调栈 &#x1f6a9;有效的括号 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 1&#xf…

[初阶数据结构] 包装类 | 泛型

目录 一. 包装类 1.1 什么是包装类? 1.2 包装类的意义 1.3 基本数据类型与包装类 1.4 装箱 1.5 拆箱 1.6 小总结 二. 泛型 2.1 什么是泛型? 2.2 泛型的意义 2.3 泛型的语法 2.4 泛型的编译 2.4.1 下载插件 2.4.2 分析 2.5 上界 2.6 泛型方法 2.7 小总结 三. 总结 一.…

conda虚拟环境,安装pytorch cuda cudnn版本一致,最简单方式

1、pytorch版本安装&#xff08;卸载也会有问题&#xff09; &#xff08;1&#xff09;版本如何选择参考和卸载 https://zhuanlan.zhihu.com/p/401931724 &#xff08;2&#xff09;对应版本如何安装命令 https://pytorch.org/get-started/previous-versions/ 最简答安装参考…

递推算法及相关问题详解

目录 递推的概念 训练&#xff1a;斐波那契数列 解析 参考代码 训练&#xff1a;上台阶 参考代码 训练&#xff1a;信封 解析 参考代码 递推的概念 递推是一种处理问题的重要方法。 递推通过对问题的分析&#xff0c;找到问题相邻项之间的关系&#xff08;递推式&a…

实验滤膜等分切割器八等分90mm

名称:滤膜切分器 型号: RNKF-90 适用范围:切分φ90mm玻璃纤维滤膜、石英纤维滤膜 等分数:2等分、4等分、8等分 使用方法: 1、开盖:逆时针旋转防尘盖&#xff0c;与切分台分开后&#xff0c;轻放于台面。 2、放膜:持专用镊子,镊子的长尖在下,短尖在上,取待切分滤膜1片,采样…

配置响应拦截器,全局前置导航守卫

1&#xff1a;配置响应拦截器 响应拦截器&#xff0c;统一处理接口的错误 问题&#xff1a;每次请求&#xff0c;都会有可能会错误&#xff0c;就都需要错误提示 说明&#xff1a;响应拦截器是咱们拿到数据的 第一个 数据流转站&#xff0c;可以在里面统一处理错误。 // 添…

uniapp小程序计算地图计算距离

我们拿到自身和目标距离经纬度 调用此方法即可计算出自身与目标的距离 最后我所展示的页面如下 具体效果可能会有点偏差 要求严格的可以在精细的计算一下

ant组件库日期选择器汉化

ant组件库日期选择器默认英文 如何汉化 跟着官网走不能完全实现汉化。 这里提供一个解决方案&#xff0c;首先&#xff0c;通过pnpm下载moment包。 然后引入和注册文件&#xff1a; import zhCN from ant-design-vue/es/locale/zh_CN;import moment from moment;moment.loca…

vue30:v-model语法糖的本质

在Vue.js框架中&#xff0c;v-model 是一个指令&#xff0c;用于在表单输入和应用状态之间创建双向数据绑定。它本质上是语法糖&#xff0c;意味着它提供了一种更简洁的方式来编写代码&#xff0c;而不需要显式地编写额外的代码。 具体来说&#xff0c;v-model 背后实际上是由…

外汇天眼:Equals集团发布战略评估通知:MDP不再考虑收购提议

Equals Group plc (LON)今天发布了一份关于其战略评估的通知。 Equals公司不再与Madison Dearborn Partners, LLC (MDP)就公司的收购提议进行讨论。MDP因此发布了一份声明&#xff0c;确认其不打算为公司提出收购提议。 然而&#xff0c;MDP与其投资组合公司MoneyGram Interna…

台式电脑怎么连WiFi?4个宝藏方法收藏好!

“我有一部台式电脑&#xff0c;现在不知道应该怎么操作才能让电脑正确连接WiFi&#xff0c;不知道大家有什么简单的连接方法吗&#xff1f;希望可以给我出出主意。” 随着无线网络的普及和科技的飞速发展&#xff0c;越来越多人选择使用WiFi来连接互联网。对于笔记本电脑和移动…

计算机网络(3) 字节顺序:网络字节序与IPv4

一.小端与大端 小端&#xff08;Little endian&#xff09;&#xff1a;低字节保存在内存低地址&#xff0c;高字节保存在内存高地址。 大端&#xff08;Big endian&#xff09;&#xff1a;低字节保存在内存高地址&#xff0c;高字节保存在内存低地址。 例如&#xff08;14…

Android 中USB-HID协议实现

前言 所有通过USB连接android设备进行通讯的步骤都是大同小异&#xff1a;查询usb设备列表 ——>匹配对应的设备类型&#xff08;如productid , vendorId&#xff09;等——>连接usb设备&#xff0c;找到连接通讯的节点——>配置通讯信息&#xff0c;进行通讯。以上是…

Java数据结构之ArrayList(如果想知道Java中有关ArrayList的知识点,那么只看这一篇就足够了!)

前言&#xff1a;ArrayList是Java中最常用的动态数组实现之一&#xff0c;它提供了便捷的操作接口和灵活的扩展能力&#xff0c;使得在处理动态数据集合时非常方便。本文将深入探讨Java中ArrayList的实现原理、常用操作以及一些使用场景。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨…

鸿蒙开发:通过startAbilityByType拉起垂类应用

通过startAbilityByType拉起垂类应用 使用场景 开发者可通过特定的业务类型如导航、金融等&#xff0c;调用startAbilityByType接口拉起对应的垂域面板&#xff0c;该面板将展示目标方接入的垂域应用&#xff0c;由用户选择打开指定应用以实现相应的垂类意图。垂域面板为调用…

Linux网络编程(二)Socket编程

Socket编程 一、网络套接字概念&#xff1a;socket 一个文件描述符指向一个套接字&#xff08;该套接字内部由内核借助两个缓冲区实现。&#xff09;在通信过程中&#xff0c; 套接字一定是成对出现的。二、网络字节序和主机字节序的转换函数&#xff08;ip和端口&#xff09…

代码随想录算法训练营第二十一天|530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 题目链接&#xff1a;530.二叉搜索树的最小绝对差 文档讲解&#xff1a;代码随想录 状态&#xff1a;还可以 思路&#xff1a;使用中序遍历来遍历二叉搜索树。在中序遍历过程中&#xff0c;比较当前节点和前驱节点的值&#xff0c;更新最小差值。返…

中国四大高原矢量示意图分享

我们在《中国地势三级阶梯示意图分享》一文中&#xff0c;为你分享了中国三级阶梯示意图的矢量文件。 现在&#xff0c;我们再为你分享中国四大高原的矢量示意图文件&#xff0c;你可以在文末查看文件的领取方法。 我国四大高原是如何划分的&#xff1f; 中国四大高原分别为…

你觉得前端开发人员有必要学习Rust吗?

有必要&#xff0c;为什么&#xff1f; 1. 性能优势 Rust能编译成高效的机器码&#xff0c;这对于需要高性能处理的前端项目尤其有利。例如&#xff0c;处理复杂的数据计算或图像处理时&#xff0c;Rust可以提供接近于C/C的性能&#xff0c;同时避免诸如内存泄漏或缓冲区溢出…

2024中国网络安全产品用户调查报告(发布版)

自2020年始&#xff0c;人类进入了21世纪的第二个十年&#xff0c;全球进入了百年未有之大变局&#xff0c;新十年的开始即被新冠疫情逆转了全球化发展的历程&#xff0c;而至2022年3月俄乌战争又突然爆发&#xff0c;紧接着2023年7月“巴以冲突"皱起&#xff0c;世界快速…