C语言文件操作,linux文件操作,文件描述符,linux下一切皆文件,缓冲区,重定向

目录

C语言文件操作

如何打开文件以及打开文件方式

读写文件

关闭文件

Linux系统下的文件操作

open

宏标志位

write,read,close,lseek接口

什么是当前路径?

linux下一切皆文件

文件描述符

文件描述符排序

C语言文件操作它们究竟是如何找到文件的呢?

重定向

缓冲区


首先我们抛出一个问题——如何进行文件操作?最普遍的方式就是使用我们的高级语言如C,C++,java这样的语言级别的接口来辅助我们操作文件,对文件进行读写操作;那语言级别的接口是怎么进行文件操作的呢?这些语言级别的文件操作为什么可以做到对文件的增删查改呢?

我们先看一下,我们之前C语言阶段学习过的文件操作;

C语言文件操作

我们要进行文件操作首先要做的就是打开我们的文件;那如何打开文件呢?

如何打开文件以及打开文件方式

我们可以使用(常用)fopen这个接口来打开我们的文件,path是我们文件的路径名字,mode是打开这个文件的方式有很多不同的选项;

 文件路径:我们的路径可以是相对路径也可以是绝对路径,这里的相对路径相对的是我们可执行程序运行变成进程时所在的目录;

选项:我们的选项大致有6个,w,w+,r,r+,a,a+,这六个选项代表着我们的6种不同的打开文件的方式,下面的对这六种种方式的简介:(这是man手册中的官方简介)

下面是gpt对这6个选项的总结:

1. "r"(只读模式):用于只读操作。如果文件不存在,则打开操作失败,并返回NULL。如果成功打开文件,则文件指针会被放置在文件的开头。

2. "w"(写入模式):用于写入操作。如果文件不存在,则创建一个新文件。如果文件已存在,则会清空文件中的内容。文件指针会被放置在文件的开头。

3. "a"(追加模式):用于追加操作。如果文件不存在,则创建一个新文件。如果文件已存在,则文件指针会被放置在文件的末尾。新写入的内容会追加到文件的末尾,不会清空原有内容。

这三种基本的打开模式还可以与"+"符号结合使用,表示具有读写权限:

1. "r+"(读写模式):用于读写操作。文件指针会被放置在文件的开头。可以对文件进行读取、修改和写入操作。

2. "w+"(读写模式):用于读写操作。如果文件不存在,则创建一个新文件。如果文件已存在,则会清空文件中的内容。文件指针会被放置在文件的开头。可以对文件进行读取、修改和写入操作。

3. "a+"(读写模式):用于读写操作。如果文件不存在,则创建一个新文件。如果文件已存在,则文件指针会被放置在文件的末尾。可以对文件进行读取、修改和写入操作。

需要注意的是,在使用读写模式时,要特别小心文件指针的位置以避免错误的读取或写入操作。使用`fseek()`函数可控制文件指针的位置。

我再用我的方式总结一下:

r和w代表的就是只读只写 流(也可以看作我们打字时候的光标位置)位于文件开头,不同的是w会清空文件所有内容,并且当文件不存在时会自动创建一个文件提供给用户,而r不具备创建和消除的功能它只能读而且是从开头读;

r+和w+的区别与r和w的区别一样(创建和消除的区别)但是我们需要注意的是r+和w+它们在读写的时候流是会随着读写的位置移动的所以我们在写或者读的时候要注意流的位置,就比如我们使用r+我们先写入了一段数据我们想要读我们这个文件中所有数据的时候我们一定要把流的位置移动到文件开头不然读到的数据就是我们写入数据的后面的位置因为我们写入数据到了这里所以流的位置变了不是在文件开头了;

a和a+是以追加的形式打开文件文件不存在则创建存在则将流放置在文件结尾,a+可以读文件而a不可以;

接下来我们说说读写文件的函数:

读写文件

读:fscanf,fread, fgets

写:fprintf, fwirte, fputs

这些读写的函数就不多进行描述了在man手册中都可以清楚明了的看到它们的内容以及如何使用;

我提供一个我的记忆方式:就是和我们C语言中的gets,scanf,puts,printf一起记忆,scanf和printf只是在参数前面多了一个流参数,而fputs是在puts参数后面多了一个流,而fgets只是在gets函数的参数后面多了一个存放文件中数据的数组大小和流;(因为fgets字符串类型函数所以我们只需要提供数组大小即可fgets会自动帮我们在数组末尾加\0的)

下面是读写文件的操作示例:

关闭文件

我们打开了文件之后自然需要关闭文件,这样可以保证文件的安全性等;

fclose就是关闭文件的函数,使用也非常简单把FILE类型的指针给fclose就可以关闭文件了;

上面的就是C语言文件操作的简单复习了;

Linux系统下的文件操作

接下来我们进入重点,为什么高级语言可以对文件进行操作呢?它到底是怎么做到的?

首先,我们回顾一下我们之前的对操作系统的理解,操作系统是为进程提供安全稳定环境的软件,它负责管理我们计算机中的进程,我们使用C语言编写程序的时候所用到的软件以及库函数其实都是操作系统提供的,而我们的C语言的库函数就是在系统接口的基础上对库函数进行封装带上一系列的自定义行为,这样既可以让我们的代码跨平台服务也简化了我们的语言学习与使用;

既然C语言库函数的底层是系统调用那么C语言文件操作库函数的底层的系统调用是什么样的呢?我们下面来看看在linux下C语言的文件操作的系统调用接口;

open

对应着库函数中的fopen,open有两类函数一类是三个参数的一类是两个的;两个参数的open函数一般是只用来读文件,三个参数的函数则是我们常用的函数;

open的三个参数

第一个参数代表了我们的文件路径

第二个参数是打开文件的选项,选项常用的有:

O_RDONLY:只读

O_WRONLY:只写

O_RDWR:可读可写

上面这三个选项必须有且只有一个选项在参数中,这些参数是不是和C语言文件操作函数中的r w +选项类似,是的!因为上面的参数就是C语言选项的底层;再加上下面这几个选项就可以成功的组建出C语言文件操作函数的打开功

O_CREAT:文件不存在时通过前面的路径创建出一个文件

O_APPEND:在文件末尾追加

O_TRUNC: 清空文件

但是这么多的选项我们怎么样才能在一个参数中使用呢?这个时候就是宏标志位登场的时候啦!我们首先看看上面的选项是不是都是大写?大写的字符在C语言中一般是不是在宏定义的时候经常使用呢?

那什么是标志位?顾名思义就是位上不同的信号,一个int类型数据有32个bit位在每个位上可以有0,1两种信号,所以我们可以使用一个参数来传递32种不同的选项,某位上为0则是否为1则代表选项成立;

宏标志位

我们可以通过下面这个小程序来理解宏标志位:

#include<stdio.h>
通过宏标志位来传递参数
#define FIRST 0x1
#define SECOND 0x2
#define THIRD 0x4

void fun(int macro)
{
  if(macro&FIRST)
    printf("这是功能1\n");
  if(macro&SECOND)
    printf("这是功能2\n");
  if(macro&THIRD)
    printf("这是功能3\n");
}

int main()
{
  fun(1);//0001
  printf("-------------------\n");
  fun(2);//0010
  printf("-------------------\n");
  fun(3);//0011
  printf("-------------------\n");
  fun(4);//0100
  printf("-------------------\n");
  fun(5);//0101

  return 0;
}

现象: 

可以看到我们通过宏标志位的传递实现的多种不同功能的组合使用;

接下来我们看第三个参数

第三个参数是用来修改我们文件权限的,这也是为什么我们常使用的是三个参数的open函数的原因;当我们不使用低三个参数的时候我们会发现:

为了避免这种情况我们使用第三个参数;

我们通过传递权限的八进制数来修改权限,这里可以看我前面写的博客来理解

Linux操作系统——权限-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_75260318/article/details/132946078?spm=1001.2014.3001.5501所以我们传递需要这样来操作

 这就是open函数的使用;

write,read,close,lseek接口

write:

第一个参数是文件描述符,就是我们open打开后的返回值具体是什么,我们下面的文件描述符会详细讲解;

第二个参数就是我们的写入数据的内容,我们可以传数组,也可以传字符串;

最后一个参数就是字节数,是我们传递的数据的字节数;

write接口会向我们的内核中写入我们的buf数据,再通过内核写入到fd文件中;

read:

它的参数和上面的write没有什么不同,不过是将数据从fd文件中读取count个字节的数据到buf中;

第二个参数是我们接受数据的指针,指向存储数据的区域;

close:

关闭打开的fd文件

lseek:

用来调整文件流的位置(光标位置)

下面是我通过chat-gpt获得的关于lseek的信息:

- `fd` 是已经打开的文件的文件描述符,可以使用 `open` 函数获取。
- `offset` 是要移动的偏移量,可以为正(向文件尾部移动)或负(向文件开头移动)。
- `whence` 是指定偏移量是相对于文件开头、当前位置还是文件尾的标志。
  - 如果 `whence` 为 `SEEK_SET`,`offset` 表示文件开始位置的偏移量。
  - 如果 `whence` 为 `SEEK_CUR`,`offset` 表示当前的位置偏移量。
  - 如果 `whence` 为 `SEEK_END`,`offset` 表示文件末尾的偏移量。

什么是当前路径?

为什么我们可以把文件创建在进程当前路径中,当前路径到底是什么意思?我们在运行可执行程序后程序变成了进程,而进程在我们之前的学习中,我们知道进程有进程的pcb结构体,这个结构体中存放了进程的各种信息,那么我们运行进程时所在的路径也会被记录下来,这个路径就是当前进程所在的路径,也就是当前路径的根本意义;

下面我们通过实际现象来证明我们思路:

由此我们可以清楚的明白所谓的当前路径就是存储在进程的pcb结构体中的进程信息,我们只要通过查找进程的结构体就可以找到我们的当前路径; 

我们讲完了open的参数接下来我们得看看open的返回值,我们可以惊讶的看到open这个系统调用的返回值居然是int类型的,这说明它只返回了一些数字,而返回数字就和我们前面C语言封装函数fopen的接口有很大差别了,C语言接口返回的是一个指针类型,至少还是可以指向某个大的存储区域的,而我们这里简简单单返回一个int究竟做了什么呢?我们就要引入一个新的知识——文件描述符;

linux下一切皆文件

我们先回顾一下Linux下一切皆文件这个概念;之前的学习中我们模模糊糊知道了linux下一切皆文件,但究竟什么叫一切皆文件呢?我们的计算机是由硬件和软件组成对于我们的操作系统,操作系统把硬件一般叫做外设,而操作系统需要管理外设,来为我们用户提供服务;如何管理呢?先描述,在组织;外设无法直接与操作系统交流,于是外设的信息形成了一个个结构体,操作系统使用不同的数据结构将这些结构体组织起来,并对结构体中的信息进程增删查改来管理外设;而要对这些外设进行访问肯定要使用到open,write,read这样的接口;

通过上面的解释我们就可以很好的理解linux下一切皆文件的道理;

文件描述符

上面讲到open系统接口的返回值就是文件描述符,并且write,read,close,lseek这样的系统接口的参数都需要用到文件描述符,那么文件描述符究竟是什么;之前我们说linux下一切皆文件,所以一切的文件被打开的文件都会有包含文件属性结构体file,file中存储了文件的相关信息,

而这些文件的结构体又由打开它们的进程进行管理,进程的pcb结构体中有一个files*的指针这个指针指向了文件结构体(这个结构体装的是进程中被打开的所有文件的信息),

在files_struct结构体中又有一个file*的fd_array指针数组(也叫文件映射表)这个数组装的就是file结构体的指针,这些指针就是指向被打开文件的;

文件描述符排序

而我们的linux进程默认打开0标准输入(对应外设键盘),1标准输出(显示器),2标准错误(显示器)三个文件(外设),而数组的0,1,2三个位置就是指向这三个文件的;在C语言中0,1,2被封装成了stdin,stdout,stderr;剩下的我们自己打开的文件会跟随我们的文件的打开顺序来分配数组下标;

需要注意的是:

如果我们关闭了文件,那么文件所在的fd_array数组位置将会制空,为接下来的打开文件让开位置;

了解了这些,现在我们总算是知道了文件描述符fd究竟是什么了,文件描述符其实就是数组下标而已,我们可以通过数组下标找到,数组中的指针,通过指针找到文件信息结构体,从而找到文件;

C语言中的文件描述符fileno:由此可见C语言的FILE结构体中一定也封装了fd;事情也是如此,C语言的FILE结构体中有fileno这样的成员变量,这个成员变量就是我们系统接口中的文件描述符;

C语言文件操作它们究竟是如何找到文件的呢?

如fopen这样的函数,首先它肯定是先调用我们的系统接口open,open接口又通过进程的结构体中的files指针找到files_struct结构体,在结构体中的fd_array数组中对应封装的fileno编号,通过编号对应的数组下标找到数组中指针指向的文件结构体,从而找到文件,打开文件;这就是C语言的文件操作找到文件的全部过程;(对照上面的图片分析效果更佳)

重定向

由于linux进程默认打开了三个文件,所以我们的输入输出默认也会从我们的键盘和屏幕读写;而重定向的意思就是改变默认的读写文件;就比如我们的cat AA.txt>BB.txt,这个指令就是把AA.txt中的数据输出到BB.txt文件中,本来cat指令默认是输出到显示器上的但是由于重定向>使得输出的方向变了;

我们可以使用dup2函数进行重定向:

这个函数的作用是将fd_array文件映射表上的oldfd下标位置的指针拷贝给newfd位置的指针;

示例

重定向有输出重定向> 输入重定向<  追加重定向>> 这些重定向;(这里就不一一实现了)

缓冲区

缓冲区这一概念我们一定都很熟悉,但是我以前只知道如果输入或者输出的字符没有打印完全的话,就刷新一下缓冲区就好了,比如使用fflush(stdout)或者使用getchar读取输入缓冲区中的\n字符;这样的理解有些片面,所以现在我们来理想的面对一下缓冲区;

缓冲区是什么?

其实缓冲区就是一段内存空间,用来存储我们的数据;

缓冲区有什么用?

当没有缓冲区的时候,我们的内核之间向外设写入,每次有数据就直接写入外设这样的写透模式WT,伴随着多次的交互,有交互就一定需要外设的准备,准备就一定需要消耗时间,并且我们的各级内存之间的运行速度差距很大,消耗的时间一定更多,而多次交互就要多次消耗时间(虽然这个时间在我们看来很多但对应计算机来说太浪费时间了),为了减少内核和外设的交互次数,就出现了缓冲区这一概念;将数据放入缓冲区当缓冲区满了或者满足刷新策略的时候就刷新缓存区将数据输出;这样一来交互的次数大大减少了!

缓冲区在哪?

缓冲区其实就是一段定义好的buffer数组,我们的C语言库中有着buffer的实现,如我们使用scanf函数的时候就是先把数据写入buffer中当遇到换行时就会和内核交互将数据刷新入内核,内核也有自己的缓冲区也有自己的刷新模式;在C语言中向显示中刷新是行刷新策略向磁盘刷新一般是满刷新策略;所以用户级缓冲区在用户使用的高级语言的库中实现,而内核级缓冲区在内核的代码中实现;

模拟实现缓冲区

#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#define BUFFER_SIZE 1024
#define BUFFER_SIZE 10

typedef struct MyFILE
{
  char _buffer[BUFFER_SIZE];
  int _end;
  int _fd;
  int _end;//指向最后一个数据后面一个也可以当作是size
  int _fd;//文件描述符
}file;

file* myfopen(const char*filename,const char* mode)
@@ -68,56 +68,71 @@ void myfflush(file*stream)
  }
  write(stream->_fd,stream->_buffer,stream->_end);//载入内核缓冲区
  syncfs(stream->_fd);//载入磁盘
  stream->_end=0;
  memset(stream->_buffer,0,sizeof(stream->_buffer));
}

void myfputs(const char*str,file*stream)
{
  file*fp=stream;
  if(fp->_end+strlen(str)>=BUFFER_SIZE)
  if(fp->_end+strlen(str)>=BUFFER_SIZE)//满刷新判断,这是所以文件都需要满足的
  {
    //如果满了直接就载入内存了
    myfflush(fp);
    fp->_end=0;
    memset(fp->_buffer,0,BUFFER_SIZE);
    fprintf(stderr,"范围那里错了\n");
    while(strlen(str)>=BUFFER_SIZE)//如果刷新了之后还是满了的话
    {
      memcpy(fp->_buffer,str,BUFFER_SIZE-1);
      fp->_end=BUFFER_SIZE-1;
      stream->_buffer[fp->_end]='\0';
      str=str+BUFFER_SIZE-1;
      myfflush(fp);
    }
    //不再满了之后
    strcpy(fp->_buffer,str);
    fp->_end=strlen(str);
    //debug
    
    //printf("%s\n",fp->_buffer);
  }
  else{//不满则直接放入缓冲区
    strcpy(fp->_buffer+fp->_end,str); 
    fp->_end+=strlen(str);
  }


  strcpy(fp->_buffer+fp->_end,str); 
  fp->_end+=strlen(str);
  if(fp->_fd==1||fp->_fd==2)//如果是标准输出和标准错误时的刷新策略
  { 
    //标准输出
  
    //标准输出和标准错误
    for(int i=strlen(str)-1;i>=0;i--)
    {
    {//从后往前寻找如果有\n就刷新
      if(str[i]=='\n')
      {
        write(fp->_fd,fp->_buffer,i+1);
        if(str[i+1]!='\0')
        myfflush(fp);
        if(str[i+1]!='\0')//把\n后面没有刷新的重新放入缓冲区
        {
          fprintf(stderr,"我遇到\n");
          strcpy(fp->_buffer,fp->_buffer+(i+1));
          strcpy(fp->_buffer,str+i+1);
          fp->_end=strlen(fp->_buffer);
        }
        return;
      }
    }
  }
}

void myfclose(file *stream)
{
  myfflush(stream);
  close(stream->_fd);
}
int main()
{
  close(1);
  file *fp=myfopen("tmp.txt","w");
  fprintf(stderr,"%d\n",fp->_fd);
  myfputs("hello myfputs\n",fp);

  printf("fp :%d\n",fp->_fd);
  char str[]="12345678912345678910\n";
  myfputs(str,fp);
  myfclose(fp);
  return 0;
}

这是我模拟实现缓冲区的代码,可以辅助理解;

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

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

相关文章

【Linux从青铜到王者】进程信号

——————————————————————————————————————————— 信号入门 在了解信号之前有许多要理解的相关概念 我们可以先通过一个生活例子来初步认识一下信号 1.生活角度的信号 你在网上买了很多件商品&#xff0c;再等待不同商品快递的到来…

达梦、金仓、南大、瀚高、优炫:从社区建设看企业技术自信心

正文约950字&#xff0c;预计阅读时间2分钟 国产技术厂商在面对自身产品问题时&#xff0c;往往保持回避态度&#xff0c;不愿公之于众&#xff0c;主要原因有2方面&#xff1a; 1&#xff0c;产品技术层面问题较多&#xff0c;如某些根本性缺陷难以攻克&#xff0c;或问题发…

Python爬虫实战(基础篇)—13获取《人民网》【最新】【国内】【国际】写入Word(附完整代码)

文章目录 专栏导读背景测试代码分析请求网址请求参数代码测试数据分析利用lxml+xpath进一步分析将获取链接再获取文章内容测试代码写入word完整代码总结专栏导读 🔥🔥本文已收录于《Python基础篇爬虫》 🉑🉑本专栏专门针对于有爬虫基础准备的一套基础教学,轻松掌握Py…

vue 安装各种问题

新下载了个项目模板&#xff0c;安装包就遇到了各种各样问题 电脑&#xff1a;mac 使用npm i 等命令一直安装项目&#xff0c;然后一直报错 2534 info run canvas2.11.2 install node_modules/canvas node-pre-gyp install --fallback-to-build --update-binary 2535 info r…

Tomcat+Nginx的动静分离

1.反向代理多机 实验&#xff1a;Nginx要开启upstream(负载均衡)、location(url链接)、proxy_pass(反向代理) 配置&#xff1a;7-3做代理服务器&#xff1b;7-1 和 7-2做Tomcat服务器 关闭防火墙和selinux 1.准备配置 7-3安装nginx&#xff1b;7-1 和 7-2安装Tomcat&#xff…

Re61:读论文 PRP Get an A in Math: Progressive Rectification Prompting

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;Get an A in Math: Progressive Rectification Prompting ArXiv网址&#xff1a;https://arxiv.org/abs/2312.06867 官方实现网站&#xff1a;PRP 官方代码&#xff1a;https://github.…

iOS 17.0 UIGraphicsBeginImageContextWithOptions 崩溃处理

在升级到iOS17后你会发现&#xff0c;之前版本运行的很好&#xff0c;这个版本突然会出现一个运行闪退。报错日志为*** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)(), UIGraphics.m:410 跟踪到具体的报错位置如下所示&a…

闰年导致的哪些 Bug

每次闰年对程序员们都是一个挑战&#xff0c;平时运行好好的系统&#xff0c;在 02-29 这一天&#xff0c;好像就会有各种毛病。 虽然&#xff0c;提前一天&#xff0c;领导们都会提前给下面打招呼。但是&#xff0c;不可避免的&#xff0c;今天公司因为闰年还是有一些小故障。…

Tomcat(二) 动静分离

一、(TomcatNginx)动静分离 1、单机反向代理 利用 nginx 反向代理实现全部转发至指定同一个虚拟主机 客户端curl www.a.com 访问nginx服务&#xff0c;nginx服务通过配置反向代理proxy_pass www.a.com:8080&#xff0c;最终客户端看到的是www.a.com 实验中&#xff1a;7-3 做客…

码农世界:从入门到高手的成长攻略

&#x1f468;‍&#x1f4bb;&#x1f469;‍&#x1f4bb; 各位编程爱好者&#xff0c;欢迎来到现实而又充满挑战的码农世界。在这里&#xff0c;我们将一起探索一条如何从入门走向精通&#xff0c;最终在IT行业中找到自己位置的道路。准备好笔记本和热情&#xff0c;让我们携…

速通C语言第十三站 预处理

系列文章目录 速通C语言系列 速通C语言第一站 一篇博客带你初识C语言 http://t.csdn.cn/N57xl 速通C语言第二站 一篇博客带你搞定分支循环 http://t.csdn.cn/Uwn7W 速通C语言第三站 一篇博客带你搞定函数 http://t.csdn.cn/bfrUM 速通C语言第四站 一篇博客带…

STM32 NAND FLASH知识点

1.NAND FLASH的简介 NAND FLASH 的概念是由东芝公司在 1989 年率先提出&#xff0c;它内部采用非线性宏单元模式&#xff0c;为固态大容量内存的实现提供了廉价有效的解决方案。 NAND FLASH 存储器具有容量较大&#xff0c;改写速度快等优点&#xff0c;适用于大量数据的存储&…

VR 全景模式OpenGL原理

VR 全景模式OpenGL原理 VR 全景模式原理 VR 全景模式原理将画面渲染到球面上&#xff0c;相当于从球心去观察内部球面&#xff0c;观察到的画面 360 度无死角&#xff0c;与普通播平面渲染的本质区别在渲染图像部分&#xff0c;画面渲染到一个矩形平面上&#xff0c;而全景需…

字节跳动发布SDXL-Lightning模型,支持WebUI与ComfyUI双平台,只需一步生成1024高清大图!

字节跳动发布SDXL-Lightning模型,WebUI与ComfyUI平台,只需一步生成1024高清大图,需要的步数比 LCM 更低了! 什么是SDXL-Lightning: SDXL-Lightning 是一种快速的文本到图像生成模型。SDXL-Lightning模型的核心优势在于其创新的蒸馏策略,它可以通过几个步骤生成高质量的 1…

红黑树的简单介绍

红黑树 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出俩倍&#x…

服务器出现故障如何恢复数据?

服务器数据恢复案例之服务器raid6中3块硬盘离线导致阵列崩溃的数据恢复案例 服务器故障&#xff1a; 服务器中有一组由6块盘组建的 RAID6&#xff0c;这台网站服务器上运行MYSQL数据库和存放其它类型的文件。该组raid中有两块磁盘离线&#xff0c;管理员没有及时更换磁盘&#…

#QT(智能家居界面-界面切换)

1.IDE&#xff1a;QTCreator 2.实验 3.记录 &#xff08;1&#xff09;创建一个新界面&#xff08;UI界面&#xff09; &#xff08;2&#xff09;可以看到新加入一个ui文件&#xff0c;双击打开&#xff0c;设置窗口大小与登录界面一致 &#xff08;3&#xff09;加入几个PUS…

Linux 运维:CentOS/RHEL防火墙和selinux设置

Linux 运维&#xff1a;CentOS/RHEL防火墙和selinux设置 一、防火墙常用管理命令1.1 CentOS/RHEL 7系统1.2 CentOS/RHEL 6系统 二、临时/永久关闭SELinux2.1 临时更改SELinux的执行模式2.2 永久更改SELinux的执行模式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;…

【CSP试题回顾】201312-3-最大的矩形

CSP-201312-3-最大的矩形 解题思路 1. 遍历所有可能的矩形高度&#xff1a; 通过遍历所有矩形高度来找到最大的矩形&#xff0c;即对每个可能的高度 it&#xff08;从直方图中的最小高度到最大高度 heightMax&#xff09;&#xff0c;代码将尝试找到在这个高度或以上的最长连…

Linux常用命令(超详细)

一、基本命令 1.1 关机和重启 关机 shutdown -h now 立刻关机 shutdown -h 5 5分钟后关机 poweroff 立刻关机 重启 shutdown -r now 立刻重启 shutdown -r 5 5分钟后重启 reboot 立刻重启 1.2 帮助命令 –help命令 shutdown --help&#xff1a; ifconfig --help&#xff1a;查看…