【linux深入剖析】基础IO操作 | 使用Linux库函数实现读写操作 | 文件相关系统调用接口

news2024/11/18 6:25:39

🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

在这里插入图片描述


目录

  • 前言
  • 1.复习C文件IO相关操作
    • 1.1 fopen函数
      • 1.1.1 w模式
      • 1.1.2 a模式
    • 1.2 fwrite函数
      • 函数介绍
      • 函数使用
    • 1.3 fgets函数
  • 2.程序默认打开的文件流
  • 3. 系统文件I/O
    • 标志位flag
    • w清空文件
    • a追加文件
    • r读取文件内容
    • open函数返回值


前言

本节的学习我们需要弄清几个概念

  1. 文件 = 内容 + 属性
  2. 访问文件之前,都得先打开,然后再进行修改文件的操作,通过执行代码的方式完成修改,这期间文件必须被加载到内存中—内存文件
  3. 打开文件的操作是通过进程的形式来实现的
  4. 一个进程可以打开多个文件
  5. 进程没有打开的文件会被存在在磁盘中—磁盘文件
    一定时间段内,系统中存才多个进程,也可能同时存在更多的被打开的文件,操作系统(OS)要不要管理多个被进程打开的文件呢?

这个答案是肯定的,但是我们更需要理解的是其如何对这些进行管理的?
先描述再组织
内核中一定要有描述被打开文件的结构体,并用其定义对象

1.复习C文件IO相关操作

C语言提供了一些文件操作函数,用于对文件进行读写和管理。以下是一些常用的C语言文件操作函数:

  1. fclose():关闭文件。语法为:int fclose(FILE *stream);
  2. fgetc():从文件中读取一个字符。语法为:int fgetc(FILE *stream);
  3. fputc():将一个字符写入文件。语法为:int fputc(int c, FILE *stream);
  4. fgets():从文件中读取一行字符串。语法为:char *fgets(char *str, int n, FILE *stream);
  5. fputs():将一个字符串写入文件。语法为:int fputs(const char *str, FILE *stream);
  6. fprintf():将格式化的数据写入文件。语法为:int fprintf(FILE *stream, const char *format, …);
  7. fscanf():从文件中读取格式化的数据。语法为:int fscanf(FILE *stream, const char *format, …);
  8. fseek():设置文件指针的位置。语法为:int fseek(FILE *stream, long offset, int origin);
  9. ftell():获取当前文件指针的位置。语法为:long ftell(FILE *stream);
  10. rewind():将文件指针重置到文件开头。语法为:void rewind(FILE *stream);
  11. feof():检查文件结束标志。语法为:int feof(FILE *stream);

以上是一些常用的C语言文件操作函数,你可以根据需要选择适合的函数来进行文件操作。

1.1 fopen函数

我们先认识一下fopen函数

fopen是一个C语言中的标准库函数,用于打开文件。它的原型如下:
FILE *fopen(const char *filename, const char *mode);
其中,filename是要打开的文件名,mode是打开文件的模式。fopen函数返回一个指向FILE结构的指针,该结构用于后续对文件进行读写操作。

常见的文件打开模式有以下几种:

  • “r”:以只读方式打开文件,文件必须存在。
  • “w”:以写入方式打开文件,如果文件不存在则创建,如果文件存在则清空内容。
  • “a”:以追加方式打开文件,如果文件不存在则创建。
  • “rb”、“wb”、“ab”:以二进制模式打开文件,用于处理二进制文件。
  • fopen函数还可以用于打开其他类型的文件,例如网络流、设备文件等。

linux系统下的打开模式:
在这里插入图片描述
注意,在使用完文件后,需要使用fclose函数关闭文件,以释放资源。

1.1.1 w模式

#include<stdio.h>

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

  fclose(fp);
  return 0;
}

运行结果:
在这里插入图片描述


加上一点文件操作:

#include<stdio.h>

int main()
{
  FILE *fp = fopen("./log.txt","w");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  //文件操作
  const char *str = "hello file\n";
  fputs(str,fp);
  
  fclose(fp);
  return 0;
}

运行结果:
在这里插入图片描述


将文件操作注释掉:

#include<stdio.h>

int main()
{
  FILE *fp = fopen("./log.txt","w");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  //文件操作
  //const char *str = "hello file\n";
  //fputs(str,fp);
  

  fclose(fp);
  return 0;
}

运行结果:
在这里插入图片描述
结果刚刚写入的hello file被清空了

结论:
以W方式访问文件时,首先清空原始文件,如果没有文件,会进行创建文件,在文件的开头对文件进行修改。


echo命令+重定向:
在这里插入图片描述
可以发现其本质就是我们的w模式,文本文件会被清空然后再往其中进行写入,我们单纯使用重定向(大于符号),文件会直接被清空


1.1.2 a模式

#include<stdio.h>

int main()
{
  FILE *fp = fopen("./log.txt","a");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  //文件操作
  const char *str = "hello file\n";
  fputs(str,fp);
  

  fclose(fp);
  return 0;
}

运行结果:
在这里插入图片描述

a模式本质也是写入,只不过其写入是追加在文件末尾


echo命令+追加重定向:
在这里插入图片描述
可以发现其本质就是我们的a模式


1.2 fwrite函数

函数介绍

fwrite是C语言中的一个函数,用于将数据块写入文件。它的原型如下:

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

参数说明:

ptr:指向要写入的数据块的指针。
size:每个数据块的字节数。
count:要写入的数据块的数量。
stream:指向要写入的文件的指针。

fwrite函数将数据块从内存写入到文件中。它会返回成功写入的数据块数量。如果返回值与count不相等,可能表示写入失败或者到达了文件末尾。
使用fwrite函数时,需要注意以下几点:

  • 写入的数据块大小应与实际数据类型相匹配,以避免数据损坏或类型错误。
  • 写入的文件必须以二进制模式打开,以确保数据以原始格式写入文件。
  • 写入的文件必须存在且可写。

函数使用

#include<stdio.h>
#include<string.h>

int main()
{
  FILE *fp = fopen("./log.txt","a");
  if(fp == NULL)
  {
    perror("fopen");
    return 1;
  }
  //文件操作
  const char *str = "hello file\n";
  fputs(str,fp);
  int count = 5;
  while(count--)
  {
    fwrite(str,strlen(str),1,fp);
  }
  
  fclose(fp);
  return 0;
}

运行结果:
在这里插入图片描述

对log.txt文件中写入了6个hello file,fputs写了一个,fwrite写了5个

1.3 fgets函数

fgets是C语言中的一个函数,用于从文件或标准输入流中读取一行字符串。它的函数原型如下:
char *fgets(char *str, int n, FILE *stream);
其中,str是一个指向字符数组的指针,用于存储读取到的字符串;n是一个整数,表示最多读取的字符数(包括换行符和空字符);stream是一个指向FILE结构的指针,表示要读取的文件流。

  1. fgets函数会从指定的文件流中读取一行字符串,并将其存储到str所指向的字符数组中。它会读取n-1个字符,或者直到遇到换行符(‘\n’)为止。如果成功读取到字符串,则会在字符串末尾添加一个空字符(‘\0’)作为结束标志。
  2. fgets函数的返回值是一个指向str的指针,如果成功读取到字符串,则返回该指针;如果到达文件末尾或发生错误,则返回NULL。
  3. 需要注意的是,fgets函数会将换行符也读取进来,并存储在字符串中。如果不希望包含换行符,可以使用字符串处理函数(如strlen和strtok)来去除它。
#include<stdio.h>
#include<string.h>

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

  char buffer[64];
  while(1)
  {
    char *r = fgets(buffer,sizeof(buffer),fp);
    if(!r) break;

    printf("%s",buffer);
  }
  
  fclose(fp);
  return 0;
}

在这里插入图片描述

2.程序默认打开的文件流

C默认会打开三个输入输出流,分别是stdin, stdout, stderr
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针

stdin、stdout和stderr是与输入输出相关的三个标准流。它们在计算机程序中起着重要的作用。

  1. stdin(标准输入):stdin是程序接收输入数据的标准输入流。它通常与键盘输入相关联,用于从用户那里接收输入。程序可以通过读取stdin来获取用户输入的数据。

  2. stdout(标准输出):stdout是程序输出结果的标准输出流。它通常与屏幕输出相关联,用于向用户显示程序的输出结果。程序可以通过将数据写入stdout来输出结果。

  3. stderr(标准错误):stderr是程序输出错误信息的标准错误流。它通常也与屏幕输出相关联,用于向用户显示程序的错误信息。与stdout不同的是,stderr主要用于输出程序运行过程中的错误和异常信息。

这三个标准流在程序中起着重要的作用,它们可以通过重定向进行控制。例如,可以将stdin重定向到文件中,以便从文件中读取输入;可以将stdout和stderr重定向到文件中,以便将输出结果和错误信息保存到文件中。

stdout就是我们的显示器,于是我们就多了几种打印的方式:

#include<stdio.h>
#include<string.h>

int main()
{
  printf("hello printf\n");
  fputs("hello file\n",stdout);
  const char *msg="hello fwrite\n";
  fwrite(msg,1,strlen(msg),stdout);
  fprintf(stdout,"hello fprintf\n");
  return 0;
}

在这里插入图片描述
stdin是程序接收输入数据的标准输入流。我们可以这样输入:

#include<stdio.h>
#include<string.h>

int main()
{
  char buffer[64];
  fscanf(stdin,"%s",buffer);
  
  printf("%s",buffer);
  return 0;
}

在这里插入图片描述


3. 系统文件I/O

操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问,先来直接以代码的形式,实现和上面一模一样的代码:

我们先认识Linux的open接口
Linux的open接口是用于打开文件或创建文件的系统调用函数。它的原型如下:

man 2 open

在这里插入图片描述
其中,pathname参数是文件路径名,flags参数指定了打开文件的方式和行为,mode参数用于指定新创建文件的权限。

flags参数可以使用以下常用的标志位进行组合:

O_RDONLY:只读方式打开文件。
O_WRONLY:只写方式打开文件。
O_RDWR:读写方式打开文件。
O_CREAT:如果文件不存在,则创建文件。
O_EXCL:与O_CREAT一起使用,如果文件已存在则返回错误。
O_TRUNC:如果文件存在且以写方式打开,则将其长度截断为0。
O_APPEND:以追加方式打开文件,即每次写操作都追加到文件末尾。

mode参数用于指定新创建文件的权限,它是一个八进制数,常用的权限值有:

S_IRUSR:用户可读权限。
S_IWUSR:用户可写权限。
S_IXUSR:用户可执行权限。
S_IRGRP:组可读权限。
S_IWGRP:组可写权限。
S_IXGRP:组可执行权限。
S_IROTH:其他人可读权限。
S_IWOTH:其他人可写权限。
S_IXOTH:其他人可执行权限。

如果open函数调用成功,则返回一个非负整数的文件描述符,该文件描述符可以用于后续的读写操作。如果调用失败,则返回-1,并设置errno变量来指示错误原因。

标志位flag

标志位flag类似于一个一个宏,我们在如下代码使用按位与实现对12345的输出,另一方面模拟实现了open接口里的flag

#include<stdio.h>

#define ONE 1
#define TWO (1<<1)
#define THREE (1<<2)
#define FOUR (1<<3)
#define FIVE (1<<4)

void Print(int flag)
{
  if(flag & ONE) printf("1\n");
  if(flag & TWO) printf("2\n");
  if(flag & THREE) printf("3\n");
  if(flag & FOUR) printf("4\n");
  if(flag & FIVE) printf("5\n");

}
int main()
{
  Print(ONE);
  printf("-------------------------\n");
  Print(TWO);
  printf("-------------------------\n"); 
  Print(ONE|TWO);
  printf("-------------------------\n");
  Print(THREE|FOUR|FIVE);
  printf("-------------------------\n");
  Print(ONE|TWO|THREE|FOUR|FIVE);
  return 0;
}

在这里插入图片描述


w清空文件

  1. 我们可以使用open接口以写的形式打开文件
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
  int fd = open("log.txt",O_WRONLY);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  return 0;
}

因为什么都没做。

在这里插入图片描述

删掉log.txt后,便会报错

在这里插入图片描述


  1. 我们可以使用open接口以写的形式打开文件,并实现文件不存在时创建文件
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  return 0;
}

在这里插入图片描述
这里文件权限上出现了S,这是我们从没见过的参数,也就是权限位乱码了,这是因为我们使用C语言新建的文件,并不是系统默认的
所以我们在实现创建文件的操作时,我们需要告诉系统文件的权限


  1. 我们可以使用open接口以写的形式打开文件,并实现文件不存在时创建文件(改良)

mode参数那里我们填入普通文件权限0666权限掩码

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

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  return 0;
}

在这里插入图片描述


  1. 我们可以使用open接口以写的形式打开文件,并实现文件不存在时创建文件,往其中写入文件
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  
  const char* str="hello system call\n";
  write(fd,str,strlen(str));

  close(fd);
  return 0;
}

在这里插入图片描述


  1. 我们可以使用open接口以写的形式打开文件,并实现文件不存在时创建文件,往其中写入文件,文件里有内容验证是否去清空文件内容重新写入
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT,0666);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  
  const char* str="aaaa\n";
  write(fd,str,strlen(str));

  close(fd);
  return 0;
}

在这里插入图片描述

在这里并没有清空源文件的内容,只是在开头用aaaa\n替换了开头五个字符长度的字符串


  1. 实现清空(实现w模式)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  
  const char* str="aaaa\n";
  write(fd,str,strlen(str));

  close(fd);
  return 0;
}

在这里插入图片描述


a追加文件

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

int main()
{
  int fd = open("log.txt",O_WRONLY|O_CREAT|O_APPEND,0666);  //以写的方式打开
  if(fd == -1)
  {
    perror("open");
    return 1;
  }
  
  const char* str="aaaa\n";
  write(fd,str,strlen(str));

  close(fd);
  return 0;
}

在这里插入图片描述


r读取文件内容

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
	int fd = open("log.txt", O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return 1;
	}
 	const char *msg = "hello bit!\n";
 	char buf[1024];
 	while(1)
 	{
 		ssize_t s = read(fd, buf, strlen(msg));//类比write
 		if(s > 0)
 		{
 			printf("%s", buf);
 		}
 		else
 		{
 			break;
 		}
 	}
	close(fd);
	return 0;
}

在这里插入图片描述


open函数返回值

open的函数返回值不是int吗?我们来输出一下

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
  int fd1 = open("log.txt", O_WRONLY);
  int fd2 = open("log.txt", O_WRONLY);
  int fd3 = open("log.txt", O_WRONLY);
  int fd4 = open("log.txt", O_WRONLY);
  int fd5 = open("log.txt", O_WRONLY);
  
  printf("fd1: %d\n",fd1);
  printf("fd2: %d\n",fd2);
  printf("fd3: %d\n",fd3);
  printf("fd4: %d\n",fd4);
  printf("fd5: %d\n",fd5);

 return 0;
}

在这里插入图片描述
这里为什么是34567?为啥不见012呢?
这是因为012已经被默认使用了

0:标准输入
1:标准输出
2:标准错误


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

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

在这里插入图片描述
我们之前的标准输入、标准输出、标准错误

在这里插入图片描述
其类型都是FILE,这其实是我们C语言库里的一个结构体,如果他们能变成我们的012,必须是在其内部封装了

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
  printf("%d\n",stdin->_fileno);
  printf("%d\n",stdout->_fileno);
  printf("%d\n",stderr->_fileno);
  int fd1 = open("log.txt", O_WRONLY);
  int fd2 = open("log.txt", O_WRONLY);
  int fd3 = open("log.txt", O_WRONLY);
  int fd4 = open("log.txt", O_WRONLY);
  int fd5 = open("log.txt", O_WRONLY);
  
  printf("fd1: %d\n",fd1);
  printf("fd2: %d\n",fd2);
  printf("fd3: %d\n",fd3);
  printf("fd4: %d\n",fd4);
  printf("fd5: %d\n",fd5);

 return 0;
}

在这里插入图片描述

结论:

  1. C语言的文件接口,本质就是封装了系统调用!

我们使用的fopen就相当于我们的open接口调用了不同的标志位,也就是我们的C语言对于文件的接口都是对系统调用进行封装的结果

  1. 为什么C语言要封装?

这是为了C语言的可移植性,在不同系统都可以调用,保证C语言的平台性

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

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

相关文章

设计模式深度解析:深入浅出的揭秘游标尺模式与迭代器模式的神秘面纱 ✨

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 深入浅出的揭秘游标尺模式与迭代器模式的神秘面纱 开篇&#xff1a; 欢迎来到设计模式的神秘…

如何在数字化转型中确保数据安全

随着科技的飞速发展&#xff0c;数字化转型已成为企业发展的必然趋势。数字化转型是指企业利用数字技术对业务流程、组织结构和商业模式进行全面创新和变革&#xff0c;以提高企业的竞争力和创新能力。然而&#xff0c;在数字化转型过程中&#xff0c;数据安全问题日益凸显&…

胖东来:超越零售巨头山姆和Costco的秘密武器

在零售业的江湖中&#xff0c;胖东来这个名字正在悄然崭露头角。3月26日&#xff0c;胖东来创始人于东来豪言壮志地表示&#xff0c;未来3-5年内&#xff0c;他的目标是超越零售巨头山姆和Costco。这不仅仅是一个口号&#xff0c;而是胖东来凭借自身实力&#xff0c;逐步迈向更…

为什么requests不是python标准库?

在知乎上看到有人问&#xff1a;为什么requests不是python标准库&#xff1f; 这确实是部分人困惑的问题&#xff0c;requests作为python最受欢迎的http请求库&#xff0c;已经成为爬虫必备利器&#xff0c;为什么不把requests直接装到python标准库里呢&#xff1f;可以省去第…

什么是公网IP?

公网IP&#xff0c;即公开网络IP地址&#xff0c;是指在互联网中公开可见、可访问的IP地址。每个设备在连接互联网时&#xff0c;都需要一个唯一的公网IP地址&#xff0c;以便其他设备可以定位并与之通信。 尽管公网IP在网络通信中具有重要作用&#xff0c;但它也带来了一些安全…

扫码登录到底是怎么实现的?

扫码登录的原理&#xff0c;其实很简单。 扫码登录的本质是&#xff0c;通过已经登录过的 App 应用&#xff0c;扫描未登录的 Web 端程序中的二维 码&#xff0c; 通过某种机制触发登录凭证的写入从而实现 Web 端自动登录的过程。 1、首先&#xff0c;在网页端打开登录页面&…

低功耗电子方案开发定制

低功耗电子方案开发定制 东莞市酷得智能科技有限公司是一家专注于为客户提供高质量解决方案的创新型科技公司。成立于2018年&#xff0c;我们的使命是通过技术创新和卓越的服务&#xff0c;帮助客户实现业务目标和价值最大化。 作为一家小而精悍的公司&#xff0c;我们拥有一支…

QML | JavaScript作用域和命名解析2

QML | JavaScript作用域和命名解析3.绑定的作用域对象 属性绑定是QML中最常见的JavaScript应用。属性绑定关联了一个JavaScript表达式的结果和对象的一个属性,该属性所归属的对象被称为绑定的作用域对象。在下面的代码中,Item对象就是一个绑定的作用域对象: ​ 绑定可以…

uniapp流浪动物救助小程序Java宠物领养小程序springboot

uniapp流浪动物救助小程序Java宠物领养小程序springboot 代码40块&#xff0c;需要的私聊 前台基于uniapp小程序 后台管理基于springbootvue前后端分离项目 开发语言&#xff1a;Java 框架&#xff1a;springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xf…

张宇1000题要刷崩溃了值不值得坚持做?

可以做1000题&#xff0c;但是复习效果可能不理想&#xff0c;因为1000题的内容难度高&#xff0c;最好基础好&#xff0c;能全程跟张宇的选择&#xff0c;否则容易浪费时间。 从题型上来看&#xff0c;1000题更注重于综合类的题目&#xff0c;题型上有些非常规。 使用1000题…

每日一题 --- 链表相交[力扣][Go]

链表相交 题目&#xff1a;面试题 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交**&#xff1a;** 题目数据 保证 整个链式结…

【计算机操作系统】深入探究CPU,PCB和进程工作原理

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

【前端】Layui的表格常用功能,表单提交事件,表格下拉按钮点击事件,表格外的按钮点击事件

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《前端》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握…

短袖有什么牌子可以推荐?质量最好的短袖品牌推荐

天气转热&#xff0c;大家都开始给自己选一些穿着舒适且好看的短袖。但是不少朋友都应该发现&#xff0c;目前市面上的服装品牌质量参差不齐&#xff0c;而且有一些短袖穿身上还会瘙痒等情况&#xff0c;尤其是大家喜欢入手的网红或明星代言的牌子更严重。 那么短袖应该怎么选…

spring 的理解

spring 的理解 spring 是一个基础的框架&#xff0c;同时提高了一个Bean 的容器&#xff0c;用来装载Bean对象spring会帮我们创建Bean 对象并维护Bean对象 的生命周期。在spring 框架上&#xff0c;还有springCloud,spring Boot 的技术框架&#xff0c;都是以Spring为基石的sp…

centos7 使用docker安装了mongo 怎么设置远程链接,必须使用密码才能连接

docker run -d –name mongodb_container -e MONGO_INITDB_ROOT_USERNAMEroot -e MONGO_INITDB_ROOT_PASSWORDroot -e MONGO_INITDB_DATABASEdataserver -p 27017:27017 \ 无法在mongo容器里编辑文件 如果你无法直接编辑 MongoDB 容器内的配置文件&#xff0c;你可以尝试…

ClickHouse10-ClickHouse中Kafka表引擎

Kafka表引擎也是一种常见的表引擎&#xff0c;在很多大数据量的场景下&#xff0c;会从源通过Kafka将数据输送到ClickHouse&#xff0c;Kafka作为输送的方式&#xff0c;ClickHouse作为存储引擎与查询引擎&#xff0c;大数据量的数据可以得到快速的、高压缩的存储。 Kafka大家…

碳课堂|什么是碳资产?企业如何进行碳资产管理?

碳资产是绿色资产的重要类别&#xff0c;在全球气候变化日益严峻的背景下备受关注。在“双碳”目标下&#xff0c;碳资产管理是企业层面实现碳减排目标和低碳转型的关键。 一、什么是碳资产&#xff1f; 碳资产是以碳减排为基础的资产&#xff0c;是企业为了积极应对气候变化&…

华为昇腾asend

昇腾Ascend C编程语言 Ascend C原生支持C/C编程规范&#xff0c;通过多层接口抽象、并行编程范式、孪生调试等技术&#xff0c;极大提高了算子的开发效率&#xff0c;帮助AI 参考文章 手把手教你在昇腾平台上搭建PyTorch训练环境 - 哔哩哔哩 (bilibili.com)https://www.bilibi…

【Java面试题】计算机网络

文章目录 1.计算机网络基础1.1网络分层模型/OSI七层模型是什么&#xff1f;1.2TCP/IP四层模型是什么&#xff1f;每一层的作用&#xff1f;1.2.1TCP四层模型&#xff1f;1.2.2为什么网络要分层&#xff1f; 1.2常见网络协议1.2.1应用层常见的协议1.2.2网络层常见的协议 2.HTTP2…