【linux】基础IO+系统文件IO+文件描述符分配规则

基础IO+系统文件IO+文件描述符+文件描述符分配规则

自我名言只有努力,才能追逐梦想,只有努力,才不会欺骗自己。

喜欢的点赞,收藏,关注一下把!

1.重新谈论文件

根据前面所学知识,我们也了解一些文件的相关知识:

1.空文件,也要在磁盘占据空间

2.文件=文件内容+文件属性

3.文件操作=对内容+对属性 or 对内容和属性

4.标定一个文件,必须使用:文件路径+文件名【唯一性】

5.如果没有指定对应的文件路径,默认是在当前路径(进程当前的路径),进行访问
6.当我们把fopen,fclose,fwrite,fread接口写完之后,代码编码之后,形成一个二进制可执行程序之后,但是没有运行,文件对应的操作有没有被执行?

其实并没有,对文件的操作,本质:进程对文件的操作!

7.一个文件如果没有被打开,可以直接进行文件访问吗?

不能,一个文件要被访问,必须先被打开。 那么被谁打开呢?

对文件的操作,是在进程中进行的,因此首先是用户进程,其次对文件操作的C接口是封装了系统调用接口,这部分是由OS操作的。

因此是由用户进程+OS共同进行的。

是不是所有文件都被打开呢?

不是,这里文件分成两类
a.被打开的文件
b.没有被打开的文件

上述这么多知识都是为了阐明一点:
文件操作的本质:进程+被打开文件的关系

2.重谈文件操作(C语言)

1.C,C++,Java,python...shell都有对文件操作的接口,但是接口都不一样

根据目前掌握的知识,了解文件在磁盘 里,而磁盘是 一个硬件OS能访问硬件 ,因此所有人想访问磁盘都绕不过OS使用的是OS提供的接口 ,想访问的是磁盘上的文件,因此使用的是OS提供文件级别的系统调用接口所有语言访问文件接口五花八门,但是操作系统只有一个。

所以上层语言无论如何变化
a.库函数底层都必须调用系统调用接口
b.库函数可以千变万化,但是底层不变

为了降低学习成本------->学习不变的东西

2.1C文件接口

2.文件的操作(C语言)

在C的时候学过文件相关操作知识,这里不再详细说,对这块知识记得不清的可以参考这篇博客超详细C语言文件操作,学完对文件了解更进一步

fopen打开文件,必须要提供打开的方式。这里总结一下

r(读),w(写),

r+(读写,文件不存在报错),w+(读写,文件不存在创建),

a(append,追加),a+(在文件尾读写,文件不存在创建),

rb(读(二进制)),wb(写(二进制)),

rb+(读写(二进制),报错),wb+(读写(二进制),创建)

ab(二进制文件尾追加),ab+(二进制文件尾读写,创建)


c 复制代码
   1 #include<stdio.h>
  2 
  3 int main()
  4 {
  5     //打开
  6     FILE* fp=fopen("log.txt","w");
  7     if(fp == NULL)
  8     {
  9         perror("fopen");
 10         return 1;
 11     }
 12 
 13     //写
 14     int cnt=5;
 15     while(cnt)
 16     {
 17         fprintf(fp,"%s:%d\n","hello linux",cnt--);
 18     }
 19 
 20     //关闭                                                                                                                                                       
 21     fclose(fp);          
 22     return 0;            
 23 }  


c 复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 
  4 int main()
  5 {
  6     //打开
  7    // FILE* fp=fopen("log.txt","w");
  8     FILE* fp=fopen("log.txt","r");
  9     if(fp == NULL)
 10     {
 11         perror("fopen");
 12         return 1;
 13     }
 14 
 15    // //写
 16    // int cnt=5;
 17    // while(cnt)
 18    // {
 19    //     fprintf(fp,"%s:%d\n","hello linux",cnt--);
 20    // }
 21 
 22    //读
 23     char buffer[64];
 24     while(fgets(buffer,sizeof(buffer)-1,fp) !=  NULL)
 25     {
 26         buffer[strlen(buffer)-1]=0;
 27         puts(buffer);                                                                                                                                            
 28     }
 29 
 30     //关闭
 31     fclose(fp);
 32     return 0;
 33 }


追加

c 复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 
  4 int main()
  5 {
  6     //打开
  7    // FILE* fp=fopen("log.txt","w");
  8    // FILE* fp=fopen("log.txt","r");
  9     FILE* fp=fopen("log.txt","a");
 10     if(fp == NULL)
 11     {
 12         perror("fopen");
 13         return 1;
 14     }
 15 
 16    //写                                                                                                                                                          
 17    int cnt=5;
 18    while(cnt)
 19    {
 20        fprintf(fp,"%s:%d\n","hello linux",cnt--);
 21    }
 22 
 23   // //读
 24   //  char buffer[64];
 25   //  while(fgets(buffer,sizeof(buffer)-1,fp) !=  NULL)
 26   //  {
 27   //      buffer[strlen(buffer)-1]=0;
 28   //      puts(buffer);
 29   //  }
 30 
 31     //关闭
 32     fclose(fp);
 33     return 0;
 34 }


以w方式单词的打开文件,C会自动清空内部数据

c 复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 
  4 int main()
  5 {
  6     //打开
  7     FILE* fp=fopen("log.txt","w");
  8    // FILE* fp=fopen("log.txt","r");
  9    // FILE* fp=fopen("log.txt","a");
 10     if(fp == NULL)
 11     {
 12         perror("fopen");
 13         return 1;
 14     }                  
 15                        
 16  //  //写
 17  //  int cnt=5;        
 18  //  while(cnt)        
 19  //  {                                                                                                                                                           
 20  //      fprintf(fp,"%s:%d\n","hello linux",cnt--);  
 21  //  }                 
 22                        
 23   // //读              
 24   //  char buffer[64];  
 25   //  while(fgets(buffer,sizeof(buffer)-1,fp) !=  NULL)  
 26   //  {                
 27   //      buffer[strlen(buffer)-1]=0;  
 28   //      puts(buffer);  
 29   //  }               
 30                       
 31     //关闭          
 32     fclose(fp);     
 33     return 0;       
 34 } 

这些都是C语言给我提供的一些对文件操作的接口。现在来看看OS给我们提供的关于对文件操作的系统调用的接口。

3.系统文件IO

3.1open

open有两个接口,首先来讲第二个接口

第一个参数:文件名

第三个参数:权限(如果创建一个文件,告诉系统该文件的权限是什么)

第二个参数:flags(是一个标记位,告诉系统以什么方式打开文件)

O_RDONLY(只读),O_WRONLY(只写),O_RDWR(读写)

flags有很多选项,这些选项是大写的,在我们印象中这样写都是宏。

C传标记位,一个int表示一个标记位,如果想传多个标记位怎么办呢?难道要传多个int吗?

显然这样处理不好。

正确解决方法:一个整数---->32个比特位---->通过比特位传递选项(一个比特位,一个选项,比特位位置不能重复)。

c 复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 
  4 //每一个宏,对应的数值,只有一个比特位是1,彼此位置不能重叠
  5 #define ONE (1<<0)
  6 #define TWO (1<<1)
  7 #define THERE (1<<2)
  8 #define FOUR (1<<3)
  9 
 10 void show(int flags)
 11 {
 12     if(flags & ONE) printf("one\n");
 13     if(flags & TWO) printf("two\n");
 14     if(flags & THERE) printf("there\n");
 15     if(flags & FOUR) printf("four\n");
 16 }
 17 
 18 int main()
 19 {
 20 
 21     show(ONE);
 22     printf("------------------\n");
 23     show(ONE|TWO);
 24     printf("------------------\n");
 25     show(ONE|TWO|THERE);
 26     printf("------------------\n");
 27     show(ONE|TWO|THERE|FOUR);
 28     printf("------------------\n");
 29  
 30     return 0;
 31 }   

返回值:文件描述符(成功),-1(失败)

c 复制代码
  #include<stdio.h>    
  #include<string.h>    
  #include<sys/types.h>    
  #include<sys/stat.h>    
  #include<fcntl.h>    
     
  int main()    
  {    
      
      //打开    
      int fd=open("log.txt",O_WRONLY);    
      if(fd<0)    
      {    
          perror("open");    
          return 1;    
      }    
      
      //关闭                                                                                                                                                         
	  close(fd);   
	  return 0; 
 }

文件不存在,并不会自动创建。

这是因为我们调用C接口,是对底层的封装,然后让底层帮我们创建,但是现在我们直接用的就是底层,如果不给具体选项,是不会帮我们自动创建的。

c 复制代码
 #include<stdio.h>    
  #include<string.h>    
  #include<sys/types.h>    
  #include<sys/stat.h>    
  #include<fcntl.h>    
     
  int main()    
  {    
      
      //打开    
      //O_CREAT 创建
      int fd=open("log.txt",O_WRONLY|O_CREAT);    
      if(fd<0)    
      {    
          perror("open");    
          return 1;    
      }    

      //关闭                                                                                                                                                         
	  close(fd);   
	  return 0; 
 }

虽然成功创建了文件,但是这个文件权限和我们用C接口创建文件的权限是不一样的,这个是上面所说的原因一样,现在用的是系统调用接口,需要直接告诉这个文件权限是什么。

cpp 复制代码
 #include<stdio.h>    
  #include<string.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<0)    
      {    
          perror("open");    
          return 1;    
      }    
      
      //关闭                                                                                                                                                         
	  close(fd);   
	  return 0; 
 }

文件不存在,用的是有第三个参数的接口。

文件存在(已经有了权限),用的是没有第三个参数的接口。

这里可能有个疑问。我给新创建的文件权限设置是0666,为什么新创建的文件权限权限是0664呢?

文件最终权限=起始权限(0666)&(~umask(普通用户0002))

所以新创建的文件权限是0664

那我们就想新创建的文件权限就是我们设置的权限怎么办呢?

umask(0)

清掉系统默认的umask

c 复制代码
 #include<stdio.h>    
  #include<string.h>    
  #include<sys/types.h>    
  #include<sys/stat.h>    
  #include<fcntl.h>    
     
  int main()    
  {    
      umask(0);
      //打开    
      int fd=open("log.txt",O_WRONLY|O_CREAT,0666);    
      if(fd<0)    
      {    
          perror("open");    
          return 1;    
      }    
      
      //关闭                                                                                                                                                         
	  close(fd);   
	  return 0; 
 }

我们手动清楚了系统默认的umask,为什么这里还是0002呢?

注意,我们改掉的是子进程的权限,并不影响shell(还是0002)。

3.2close

关闭文件。

参数就是文件描述符。

3.3write

第一个参数:向那个文件里写

第二个参数:想写对应的缓冲区数据在哪里

为什么第二个参数用的是void呢?
语言层面把文件类型分为:1,文本文件 。2,二进制文件。
但是操作系统一律认为都是二进制文件,所以是void

第三个参数:缓冲区字节个数
返回值:成功时,写入内容的字节个数会被返回,失败时返回-1。

c 复制代码
 #include<stdio.h>
  #include<string.h>
  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>
  #include<unistd.h>
  #include<stdlib.h>
  
  int main()    
  {    
      umask(0);    
      //打开    
      int fd=open("log.txt",O_WRONLY|O_CREAT,0666);    
      if(fd<0)    
      {    
          perror("open");    
          return 1;    
      }                                                                                                                                                              
      
      //写    
	  const char* buffer="hello linux\n"; 
      ssize_t num= write(fd,buffer,strlen(buffer)); //向文件中写入string,strlen(buffer)+1 需要加1吗?  
      //你以\0作为字符串的结尾,是C语言的规定,和我文件有什么关系呢?     
	  if(num<0)    
      {
          perror("write");
          exit(2);
      }
      
      //关闭
      close(fd);
      return 0;
}
c 复制代码
 #include<stdio.h>
  #include<string.h>
  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>
  #include<unistd.h>
  #include<stdlib.h>
  
  int main()    
  {    
      umask(0);    
      //打开    
      int fd=open("log.txt",O_WRONLY|O_CREAT,0666);    
      if(fd<0)    
      {    
          perror("open");    
          return 1;    
      }                                                                                                                                                              
      
      //写    
	  //const char* buffer="hello linux\n";    
	  const char* buffer="aaaaaa\n";   
      ssize_t num= write(fd,buffer,strlen(buffer));      
	  if(num<0)    
      {
          perror("write");
          exit(2);
      }
      
      //关闭
      close(fd);
      return 0;
}

为什么是这样的结果呢?

C语言以w方式打开文件,会先清空文件内容再写。

但是open("log.txt",O_WRONLY|O_CREAT,0666);只是直接覆盖,并不会清理。

这是因为我们少传一个参数O_TRUNC。

c 复制代码
 #include<stdio.h>
  #include<string.h>
  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>
  #include<unistd.h>
  #include<stdlib.h>
  
  int main()    
  {    
      umask(0);    
      //打开    
      int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);    
      if(fd<0)    
      {    
          perror("open");    
          return 1;    
      }                                                                                                                                                              
      
      //写    
	  //const char* buffer="hello linux\n";    
	  const char* buffer="aaaaaa\n";   
      ssize_t num= write(fd,buffer,strlen(buffer));      
	  if(num<0)    
      {
          perror("write");
          exit(2);
      }
      
      //关闭
      close(fd);
      return 0;
}

以前我们C接口,fopen,以w/a方法打开文件,就是库里直接帮我们把下面工作做好了。

3.4read

第一个参数:从那个文件中读

第二个参数:读到那个缓冲区

第三个参数:读多少个字节

返回值:成功返回读取字节的个数,失败返回-1

c 复制代码
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>


int main()        
{                 
    umask(0);     
    //打开        
   //bin int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);    
    int fd=open("log.txt",O_RDONLY);    
    if(fd<0)      
    {             
        perror("open");                                                                                                                                    
        return 1;                                                                                                                                          
    }                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                            
    //读                                                                                                                                                   
   char buffer[1024];
   ssize_t num=read(fd,buffer,sizeof(buffer)-1);                                                                                                    
   if(num > 0) buffer[num-1]=0; //0,\0,NULL--->0,,系统调用接口不管读的是什么类型文件,都会当作二进制处理,这里我们想读的是字符串,因此结尾加个\0      
   puts(buffer);
   //关闭
   close(fd);
   return 0;
}

3.5lseek

重新定位读写文件的偏移量

这个函数和fseek类似,这里不再演示。

3.6总结

4.如何理解文件

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

进程可以打开多个文件吗?--->可以--->系统中一定会存在大量的被打开的文件 --->被打开打开的文件,要不要被OS管理起来呢?--->要 ---> 如何管理?---> 先描述,在组织 ---> 操作系统为了管理对应打开的文件,必定要为文件创建对应的内核数据结构标识文件 --->struct _file{ } --->包含了文件大部分属性。

c 复制代码
  #include<stdio.h>
  #include<string.h>
  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>
  #include<unistd.h>
  #include<stdlib.h>
  #define FILE_NAME(number) "log.txt"#number

  int main()
  {
      umask(0);
      //打开
     //int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
     // int fd=open("log.txt",O_RDONLY);
     int fd0=open(FILE_NAME(1),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd1=open(FILE_NAME(2),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd2=open(FILE_NAME(3),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd3=open(FILE_NAME(4),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd4=open(FILE_NAME(5),O_WRONLY|O_CREAT|O_TRUNC,0666);

  
      printf("fd0:%d\n",fd0);
      printf("fd1:%d\n",fd1);
      printf("fd2:%d\n",fd2);
      printf("fd3:%d\n",fd3);                                                                                                                                        
      printf("fd4:%d\n",fd4);
  
      close(fd0);
      close(fd1);
      close(fd2);
      close(fd3);
      close(fd4);	
      return 0;
}

文件创建成功,并且返回各自对应的文件描述符。

但是奇怪的是:

a.为什么从3开始呢?0,1,2去哪里了?

b.为什么是连续的小整数呢?--->什么会是连续的小整数呢?---> 猜测可能和数组有关

这里就不得不提到,C程序默认会打开三个标准输入,标准输出,标准错误。

FILE* fp=fopen();问FILE是什么呢?

int fd=open(); int 是文件描述符

我们知道C:fopen...是对底层系统调用接口的封装,而底层用的是文件描述符。

FILE是一个结构体 ----> 必须有一个字段存放文件描述

C调用文件函数的接口不仅对系统调用接口的封装,与此同时C语言FILE结构体也封装了操作系统内的文件描述符。

c 复制代码
 #include<stdio.h>
  #include<string.h>
  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>
  #include<unistd.h>
  #include<stdlib.h>
  #define FILE_NAME(number) "log.txt"#number

  int main()
  {
     umask(0);
     printf("stdin->fd:%d\n",stdin->_fileno);  
     printf("stdout->fd:%d\n",stdout->_fileno);  
     printf("stderr->fd:%d\n",stderr->_fileno);      
      //打开
     //int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
     // int fd=open("log.txt",O_RDONLY);
     int fd0=open(FILE_NAME(1),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd1=open(FILE_NAME(2),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd2=open(FILE_NAME(3),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd3=open(FILE_NAME(4),O_WRONLY|O_CREAT|O_TRUNC,0666);
     int fd4=open(FILE_NAME(5),O_WRONLY|O_CREAT|O_TRUNC,0666);

  
      printf("fd0:%d\n",fd0);
      printf("fd1:%d\n",fd1);
      printf("fd2:%d\n",fd2);
      printf("fd3:%d\n",fd3);                                                                                                                                        
      printf("fd4:%d\n",fd4);
  
      close(fd0);
      close(fd1);
      close(fd2);
      close(fd3);
      close(fd4);	
      return 0;
}




文件描述符的本质:就是数组的下标。

进程与文件直之间对应的关系:进程通过文件描述符来指向文件的。

5.文件描述符(fd)分配规则

c 复制代码
  1 #include<stdio.h>  
  2 #include<string.h>  
  3 #include<sys/types.h>  
  4 #include<sys/stat.h>  
  5 #include<fcntl.h>  
  6 #include<unistd.h>  
  7 #include<stdlib.h>  
  8   
  9 int main()  
 10 {  
 11     umask(0);  
 12     int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);  
 13     if(fd == -1)
 14     {
 15         perror("open");
 16         exit(1);                                                                                                                                                 
 17     }                                                                                                
 18     printf("fd:%d\n",fd);                                                                            
 19                                                                                                      
 20     close(fd);                                                                                       
 21                                                                                                      
 22     return 0;                                                                                        
 23 }       
c 复制代码
   1 #include<stdio.h>
  2 #include<string.h>
  3 #include<sys/types.h>
  4 #include<sys/stat.h>
  5 #include<fcntl.h>
  6 #include<unistd.h>
  7 #include<stdlib.h>
  8 
  9 int main()
 10 {
 11     close(0);                                                                                                                                                    
 12     umask(0);
 13     int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
 14     if(fd == -1)
 15     {
 16         perror("open");
 17         exit(1);
 18     }
 19     printf("fd:%d\n",fd);
 20 
 21     close(fd);
 22 
 23     return 0;
 24 }
c 复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<sys/types.h>
  4 #include<sys/stat.h>
  5 #include<fcntl.h>
  6 #include<unistd.h>
  7 #include<stdlib.h>
  8 
  9 int main()
 10 {
 11     close(2);                                                                                                                                                    
 12     umask(0);
 13     int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
 14     if(fd == -1)
 15     {
 16         perror("open");
 17         exit(1);
 18     }
 19     printf("fd:%d\n",fd);
 20 
 21     close(fd);
 22 
 23     return 0;
 24 }

对比三次运行结果,发现每次创建新文件fd都不同,在仔细发现这是由于close(fd)关闭文件,所导致的结果。

由图来解释上述原因

当我们关闭fd为0的文件,重新打开一个文件的时候,进程扫描文件描述符表:从小到大,按照循序寻找最小的且没有被占用的fd。(fd的分配规则)

c 复制代码
 1 #include<stdio.h>
  2 #include<string.h>
  3 #include<sys/types.h>
  4 #include<sys/stat.h>
  5 #include<fcntl.h>
  6 #include<unistd.h>
  7 #include<stdlib.h>
  8 
  9 int main()
 10 {
 11    // close(0);
 12    // close(2);
 13     close(1);                                                                                                                                                    
 14     umask(0);                                                         
 15     int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);             
 16     if(fd == -1)                                                      
 17     {                                                                 
 18         perror("open");                                               
 19         exit(1);                                                      
 20     }                                                                 
 21     printf("fd:%d\n",fd);                                             
 22                                                                       
 23     close(fd);                                                        
 24                                                                       
 25     return 0;                                                         
 26 }  

close(1),为什么没有打印新建文件fd呢?

printf("%d\n",fd); printf会把内容打印到stdout文件中。

但是close(1)关闭标准输出stdout--->显示器,int fd=open();新打开的文件fd是1。

stdout-->fd-->1,虽然我们手动关闭了stdout,但是系统并不知道,还以为fd为1的位置是stdout,但是这个位置现在已经被新打开的文件占用了,所以打印到了新打开的文件里。

c 复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<sys/types.h>
  4 #include<sys/stat.h>
  5 #include<fcntl.h>
  6 #include<unistd.h>
  7 #include<stdlib.h>
  8 
  9 int main()
 10 {
 11    // close(0);
 12    // close(2);
 13     close(1);
 14     umask(0);
 15     int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
 16     if(fd == -1)
 17     {
 18         perror("open");
 19         exit(1);
 20     }
 21     printf("fd:%d\n",fd);
 22     
 23     //这里必须刷新一下,不然log.txt里面没有内容,这里和缓冲区有关,下面讲                                                                                                                  
 24     fflush(stdout);      
 25     close(fd);           
 26                          
 27     return 0;            
 28 } 

本来应该打印到显示器文件中,但是确写到文件里了。------>重定向

有关重定向问题,下篇博文解释!

相关推荐
o(╥﹏╥)6 分钟前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
娶不到胡一菲的汪大东11 分钟前
Ubuntu概述
linux·运维·ubuntu
阿里嘎多学长20 分钟前
docker怎么部署高斯数据库
运维·数据库·docker·容器
Yuan_o_23 分钟前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
东方隐侠安全团队-千里30 分钟前
网安瞭望台第17期:Rockstar 2FA 故障催生 FlowerStorm 钓鱼即服务扩张现象剖析
网络·chrome·web安全
那就举个栗子!37 分钟前
Ubuntu 20.04下Kinect2驱动环境配置与测试【稳定无坑版】
linux·ubuntu
灯火不休➴38 分钟前
[Xshell] Xshell的下载安装使用、连接linux、 上传文件到linux系统-详解(附下载链接)
linux·运维·服务器
Lukea1138 分钟前
【新教程】Ubuntu server 24.04配置无线网WiFi
linux·ubuntu·教程
小峰编程40 分钟前
独一无二,万字详谈——Linux之文件管理
linux·运维·服务器·云原生·云计算·ai原生
卜及中41 分钟前
【Linux】资源隔离机制 — 命名空间(Namespace)详解
linux·服务器·php