linux系统基础知识-基础IO

IO

  • 概念引入
  • 位图的概念
  • IO的系统调用函数
    • open
    • write
    • read()
    • close
    • 简单使用样例:
  • 文件描述符fd
    • 默认文件流stdin/stdout/stderr
    • 文件描述符的分配规则
  • 重定向的概念
    • 输出重定向
    • 输入重定向
    • 追加重定向
    • dup2()系统调用
    • 总结
  • 文件缓冲区
    • 深入理解缓冲区的概念
    • 输出缓冲区部分代码解释
    • 总结
  • stdout和stderr的区别
    • 总结
    • 自己实现一个perror
  • 文件系统
    • inode
    • 发现系统还有空间,为什么不能创建文件?
  • 软硬链接

概念引入

在学习C语言的时候,我们学过一些文件操作的函数,比如fopen,fgets,fputs,fclose等等,其实这些函数的功能就是在操作文件,进行IO读取工作。这些是C语言封装的函数。
然而C语言封装的函数里面,一定有OS层面的动作,因为IO设计到硬件操作,而对于硬件的操作一定要通过系统调用,让OS帮助我们完成IO操作。
所以,为了更好的让大家理解IO原理,先介绍一下IO的系统调用接口。

位图的概念

在介绍系统调用函数之前,需要了解一下位图的概念。顾名思义就是每个比特位都有不通过的含义,代表着不同的功能。
下面使用一个例子介绍位图的应用:

  1 #include<stdio.h>2 3 4 // 用int中的不重复的一个bit,就可以标识一种状态5 // 第1个比特位表示功能一,第二个比特位表示功能二,第三个比特位表示功能三6 #define ONE 0x1   //0000 00017 #define TWO 0x2   //0000 00108 #define THREE 0x4 //0000 01009 10 11 void show(int flags)12 {13   //哪个标志的比特位是1,就完成对应的功能14   if(flags & ONE) printf("功能ONE\n");15   if(flags & TWO) printf("功能TWO\n");16   if(flags & THREE) printf("功能THREE\n");17 }18 19 int main()20 {21   show(ONE);   //选择功能122   show(TWO);    //选择功能223   show(ONE | TWO);   //选择功能1和224   show(ONE | TWO | THREE);  //选择功能123                                                                                                                           25   return 0;26 }

在这里插入图片描述

从上面的运行结果可以来看,我们使用位图的概念,实现了的方法可以选择任意功能。

IO的系统调用函数

open

类比fopen的使用,使用man 2 open查询open函数的用法。我们使用时,经常使用带mode的函数。
在这里插入图片描述

第一个参数:文件路径
第二个参数flags:功能位(位图的概念)
第三个参数:权限:可以使用16进制来表示,一般使用0x666表示rw权限。
返回值:成功时返回新打开的文件描述符。失败时:返回-1.

flags:打开文件时,可以传入多个参数选项,用下面的一个或多个常量进行"或"运算,构成flags。

  • O_RDONLY:只读打开
  • O_WRONLY:只写打开
  • O_RDWR:读、写打开 (上面这三个常量,必须写一个且只能写一个)
  • O_CREAT:若文件不存在,则创建它。需要使用mode选项,来指明文件的访问权限。
  • O_APPEND:追加写。

下面我们简单举个例子来打开文件:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<sys/stat.h>4 #include<fcntl.h>5 6 int main()7 {8   //只读并且没有文件创建。9   int fd = open("log.txt", O_WRONLY|O_CREAT, 0666);// rw-rw-rw                                                                                                      10   if(fd < 0)11   {12     perror("open:");13     return 1;14   }15 16   printf("打开成功, fd %d \n", fd);17 18   return 0;19 }

在这里插入图片描述

write

类比fwrite的使用,使用man 2 write查询open函数的用法。在这里插入图片描述

fd:文件描述符
buf:要写的字符串。
count:要写的大小(单位是字节)
返回值:ssize_t :实际写的有效字节数。

read()

类比fread。
在这里插入图片描述

将fd的功能读到字符串buf中,读取count个字节。

close

关闭指定文件,通过文件描述符关闭。
在这里插入图片描述

返回值:0代表成功。-1代表失败。

简单使用样例:

创建一个log.txt文件,并且追加输入111222333

  1 #include<stdio.h>2 #include<string.h>3 #include<stdlib.h>4 #include<unistd.h>5 #include<sys/types.h>6 #include<sys/stat.h>7 #include<fcntl.h>8 9 int main()10 {11   //只读并且没有文件创建,追加写入12   int fd = open("log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);// rw-rw-rw13   if(fd < 0)14   {15     perror("open:");16     return 1;17   }18 19   printf("打开成功, fd %d \n", fd);20   const char* s1 = "111111111111";21   const char* s2 = "222222222222";22   const char* s3 = "3333333333333";23   write(fd, s1, strlen(s1));24   write(fd, s2, strlen(s1));25   write(fd, s3, strlen(s1));26 27   close(fd);                                                                                                                                                        28 29   return 0;30 }

在这里插入图片描述

文件描述符fd

通过open系统调用函数的理解,发现文件描述符其实就是一个小整数,并且一直是3,为什么呢?
这就要引入stdin,stdout,stderr的概念。

默认文件流stdin/stdout/stderr

在我们操作系统启动的时候,默认会打开三个流,他们就是stdin,stdout,stderr,即标准输入流、标准输出流、标准错误流。对应的硬件分别是:键盘(让我们能输入)、显示器(让我们能看见)、显示器(出错了也能看见)。
在这里插入图片描述

看下面一段程序:

  1 #include<stdio.h>4 int main ()5 {6 7   printf("stdin: %d\n",stdin->_fileno);8   printf("stdout: %d\n",stdout->_fileno);9   printf("stderr: %d\n",stderr->_fileno);10   return 0;                                                                                                                                                         11 }12 

在这里插入图片描述
我们可以猜测,0,1,2是被这默认打开的三个流占用了,所以我们每次再打开文件的时候,被分配的就是从3开始了。


并且在man手册查看一下他们的介绍,发现都是FILE* 类型的。
在这里插入图片描述
因此我们猜测FILE是一个结构体,并且结构体的内部一定有fd。当然这个结构体一定是由C语言提供的。
而我们上面学习了系统调用函数,使用的是fd操纵的文件,我们可以推测C语言的文件操作,一定封装了系统调用的接口,并且通过struct FILE里面的fd来和系统沟通,因为系统只认识fd,不认识FILE*。

下面我将fd与文件的关系可视化出来帮助大家理解:
在这里插入图片描述

解释:通过进程的pcb里面可以找到一个数组,其中fd就是数组的下标,数组内容存着文件的属性信息。因此当我们打开一个文件的时候,OS会在数组中申请一个最小的下标(通常情况下最小为3),然后内容存上结构体的地址,这样我们就能通过fd操作文件啦。

在这里插入图片描述

现在我们知道,文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*file,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符fd就是该数组的下标。所以只要拿着文件描述符,就可以找到对应的文件。

文件描述符的分配规则

现在我们已经理清楚,文件描述符是什么,有什么用。那么他的分配规则是什么呢?fd分配最小下标分配原则。
关闭0号文件,那么我们如果打开文件的话描述符就为0,如下:

  1 #include<stdio.h>2 #include<string.h>3 #include<stdlib.h>4 #include<unistd.h>5 #include<sys/types.h>6 #include<sys/stat.h>7 #include<fcntl.h>8 9 int main()10 {12   close(0);   //关闭0号文件描述符                                                                                                                                                         13   int fd = open("log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);// rw-rw-rw14   if(fd < 0)15   {16     perror("open:");17     return 1;18   }19 20   printf("打开成功, fd %d \n", fd);28   close(fd);30   return 0;31 }

在这里插入图片描述

可以验证OS总是优先分配最小的数组下标,即便是0、1、2号下标也不例外!!!

重定向的概念

输出重定向

看一下下面的代码:

  1 #include<stdio.h>2 #include<string.h>3 #include<unistd.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 8 int main ()9 {10 11   close(1);12   int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);  //fd的文件描述符为113   //下面的内容本应该打印到屏幕上。但实际上却没有打印出来。14   printf("打开文件分配的fd为%d\n", fd);  15   printf("打印到屏幕上的内容\n");16   fprintf(stdout, "hello fprintf\n");17   const char* s1 = "hello fwrite\n";18   fwrite(s1, 1, strlen(s1), stdout);19                                                                                                              22   fflush(stdout);23   close(fd);24   return 0;25 }

运行结果:本应该显示在屏幕上的内容却被输出到了文件里!这个现象叫做输出重定向,但是为什么呢?
在这里插入图片描述

下面我将用图例解释一下产生上面情况的原因:
在这里插入图片描述
注意stdin,stdout,stderr在C语言是宏定义,分别被定义成为了0、1、2。在代码中,我们首先关闭了1号文件描述符,然后又打开了文件,显然log.txt文件的文件描述符就是1也就是说1号下标的内容由标准输出(屏幕)变成了指向log.txt的指针。所以,我们在代码中对stdout文件输出内容,在语言层面其实就是对1号文件描述符输出内容,然而语言层面不知道这个改变(因为文件描述符是OS分配的),所以就造成了输出重定向

输入重定向

理解输出重定向例子后,我们很容易就能写出输入重定向。

  8 int main ()9 {10 11   // 关闭stdin12   close(0);13   int fd = open("log.txt", O_RDONLY);14   if(fd<0)15   {16     perror("open:");17     return 1;18   }                                                                                                         19   printf("fd = %d \n", fd);20   char buffer[128];21   fgets(buffer, sizeof buffer, stdin);22   printf("buffer:%s\n", buffer);23   close(fd);}

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

可知我们本该需要使用键盘输入的时候,但是却不需要我们输入,而是从我们打开的文件中读取了一行。这就完成了输入重定向工作。

追加重定向

我们实现一直往log.txt追加输出内容的代码:

  1 #include<stdio.h>2 #include<string.h>3 #include<unistd.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 8 int main ()9 {10 11   close(1);//将文件打开方式变为追加打开即可12   int fd = open("log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);  //fd的文件描述符为113   //下面的内容本应该打印到屏幕上。但实际上却没有打印出来。14   printf("打开文件分配的fd为%d\n", fd);  15   printf("打印到屏幕上的内容\n");16   fprintf(stdout, "hello fprintf\n");17   const char* s1 = "hello fwrite\n";18   fwrite(s1, 1, strlen(s1), stdout);19                                                                                                              22   fflush(stdout);23   close(fd);24   return 0;25 }

在这里插入图片描述
运行程序前后,log.txt内容确实被追加了!

dup2()系统调用

上面的例子只是让我们见识一下重定向是什么样子。而实际工程中,我们多使用dup2()系统调用,来完成此功能。

在这里插入图片描述
在这里插入图片描述

把oldfd文件描述符的内容给nwefd(相当于修改的是数组内容)。

看下面代码示例:

  8 int main (int argc, char* argv[])9 {10   if(argc!=2)11   {12     return 1;13   }14 15   int fd = open("log.txt", O_CREAT| O_WRONLY|O_TRUNC, 0666);16   printf("fd:%d\n", fd);17   dup2(fd,1); //将stdout的内容修改为fd18   printf("打印屏幕上的内容:%s\n",argv[1]);19 20   close(fd);21   return 0;   }   

运行结果:
在这里插入图片描述
通过上面的例子,我们使用dup2完成了输出重定向!

总结

重定向的本质,其实是在OS内部,更改fd对应的内容指向!!!
重定向很容易解决Linux系统一切皆文件的设计理念。它把显示器、键盘、磁盘当成文件,全部封装成struct file,在用户看来,只需要操作对应的结构体,即可完成重定向的工作。用户根本不需要知道硬件的细节。也恰好能体现封装的思想。

文件缓冲区

  1. 什么是缓冲区?
    缓冲区就是一段内存区域,介于CPU和硬盘之间,因为要执行IO的话,CPU肯定会访问硬盘。CPU的速度是ns级别,硬盘的速度是ms级别。如果让CPU直接访问的话,肯定会拖慢系统的速度。因此我们可以在内存中开辟一小段区域,这段区域就叫做缓冲区。

  2. 缓冲区有什么用?
    缓冲区可以提高效率。
    写透模式(wrrite through):CPU直接向硬盘写入(耽误CPU时间,慢)。
    写回模式:(write back):CPU将数据写到缓冲区后,就干别的事情去了,让缓冲区自己往硬盘写入,写完报告给CPU即可。(不耽误CPU时间,快,,也可以提高用户的相应速度)。

  3. 缓冲区的刷新策略
    立即刷新(写完就立马刷新)、行刷新/行缓冲(遇到\n就立马刷新)、满刷新/全缓冲(写满缓冲区才刷新)。
    一般而言,行缓冲的设备文件:显示器;全缓冲的设备:磁盘文件

深入理解缓冲区的概念

下面我们先看一段代码:

  8 int main ()9 {10   11   //C语言提供的12   printf("hello world\n");13   const char* s1 = "hello frite\n";14   fwrite(s1, 1, strlen(s1), stdout);15   fprintf(stdout,"hello fprintf\n");16 17   //OS系统提供的接口18   const char *s2 = "hello write\n";19   write(1, s2, strlen(s2));20 21 22   fork();                                                                                                   23   return 0;24 }

程序运行结果如下:
在这里插入图片描述
**观察发现,程序运行时是正常的,但是当我们重定向到文件里面后,发现C语言提供的函数打印了两次,而系统调用函数只打印一次。**如果我们把fork去掉之后,程序正常运行。我们猜想,这种情况一定和fork有某种关系。

解释:

  1. 如果向显示器打印,刷新策略是行刷新,那么最后执行fork的时候,一定是函数执行完了同时数据已经被刷新了,此时再fork就没有意义了。
  2. 如果对应的程序进行了重定向,要向磁盘文件打印,隐形的刷新策略变成了全缓冲(\n便不管用了),fork的时候,一定是函数已经执行完了,但是数据还没有刷新!因为刷新会清空缓冲区,这涉及到写时拷贝,当父进程结束运行,会刷新缓冲区,同时触发写时拷贝,赋值给子进程,子进程退出时再刷新一份,这样就相当于打印了两次
  3. 为什么系统调用函数只打印一次呢?
    原因是,我们上面提到的缓冲区其实是C语言层面上的,调用C函数时,会将数据写到C提供的缓冲区上。而fork后,出发写时拷贝时,父进程刷新数据到OS缓冲区(1份),子进程刷新到OS缓冲区(2份),因此C语言层面上会打印两次。而write系统调用会直接将数据写到OS缓冲区,因为他是系统提供的函数,不属于C语言函数,因此不涉及C语言层面上的写时拷贝动作,因此只会刷新一次。
    下图解释了这种现象:

在这里插入图片描述

输出缓冲区部分代码解释

在这里插入图片描述

我们在输出缓冲区,当时红色框框的代码没有讲解,现在我们可以解释一下:

  1. 当我们关闭了1号文件,打开了log.txt,此时log.txt的文件描述符为1.
  2. 刷新策略由行刷新,变成了普通刷新,因为是往文件里打印,因此我们输出的数据,其实是在stdout的缓冲区里,并没有刷新呢!
  3. 如果我们提前关闭close(1),因为数据还在缓冲区里,还没有来得及刷新到文件里。所以log.txt文件里什么都没有。
  4. 当我们提前fflush文件的时候,已经把数据刷新到文件里,因此再关闭文件就没事了。

总结

所有的设备按道理来说,都倾向于全缓冲,缓冲区满了,才刷新,这样能进行更少的IO操作,提高效率。因为和外设IO时,数据量的大小不是主要矛盾,和外设预IO的过程(准备过程)是最耗费时间的。
为了照顾到用户体验,显示器一般都是行刷新。极端情况下,我们也可以自定义刷新规则。

**C语言的缓冲区在哪里呢?**和fd一样,存在FILE结构体里面,包含了该文件fd对应的语言层的缓冲区结构。

stdout和stderr的区别

stdout和stderr所对应的硬件都是显示器,但是他们具体有什么区别呢?
名字上:stdout叫标准输出流,stderr叫标准错误流。
让我们看下面一段代码:
该程序输出的1表示使用stdout打印的。输出2表示使用stderr打印的。

  1 #include<iostream>2 #include<stdio.h>3 4 int main()5 {6   //stdout -> 17   printf("hello printf 1\n");8   fprintf(stdout, "hello fprintf1\n");9 10   //stderr11   perror("hello perror 2");12 13   // cout -> 114   std::cout<< "hello cout 1"<<std::endl;15   //cerr -> 2                                                                                                        16   std::cerr<<"hello cerr 2"<<std::endl;17 18   return 0;19 }

在这里插入图片描述

程序首先都被打印到了屏幕上,证明他们对应的硬件都是显示器。

我们在此程序的基础上,运行下面的命令:
重定向后,发现stderr的输出仍然打印出来了,但是stdout的输出被重定向到log.txt。
在这里插入图片描述
结论:因为屏幕只有一个,stdin和stdout都打开了显示器文件,即一个显示器文件被打开了两次,有两个文件描述符,输出重定向只是重定向了fd=1描述符,并没有影响到stderr。因此stderr仍然打印到屏幕上。

应用:

//运行下面的命令即可把两种输出,分别重定向到两个文件里。./myfile > log.txt 2>err.txt

在这里插入图片描述

//运行下面的命令即可把两种输出,重定向到一个文件里。./myfile > log.txt 2>&1

在这里插入图片描述

总结

一般而言程序如果可能出问题的话,使用stderr或者cerr来打印。
如果是常规文本的打印,建议使用cout或者stdout打印。

自己实现一个perror

在我们的文件操作函数出错之后,出错信息一般都会存在一个全局变量,errno里面,我们一般都使用perror函数来打印错误信息,但是该接口不需要errno。说明该接口一定封装了errno。代码如下:

  5 void myperror(const char* s)6 {7   //使用errno全局变量打印错误8   fprintf(stderr, "%s %s\n",s, strerror(errno));9 }

文件系统

文件系统顾名思义是管理文件的系统。如下图是Linux ext2文件系统的磁盘文件系统图。
磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是格式化的时候确定的,并且不能更改。其中启动块(Boot Block)的大小是确定的。
在这里插入图片描述

  • Block Group:块组,文件系统会根据分区的大小划分为好多个Block Group。而每个Block Group有着相同的结构。
  • 超级块(Super Block):存放(整个)文件系统本身的结构信息。记录的主要信息有:block和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检查磁盘的时间等其他文件系统的相关信息。Super Block如果被损坏,整个文件系统就被破坏了。因此,有好多个Block Group都有Super Block。
  • GDT(Group Descriptor Table):块组描述符,描述块组的属性信息,这个块组多大,已经使用了多少,有多少inode,已经占用了多少,还剩多少,一共有多少个block,使用了多少。
  • 块位图(Block Bitmap):位图中记录着哪个数据块已经被占用,哪个数据块没有被占用。
  • inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
  • inode Table:i结点表,存放文件属性和文件大小,所有者,最近修改时间等。
  • Data blocks:数据区存放文件内容。

众所周知:文件 = 属性 + 数据因此flie = inode Table + Data blocks

inode

inode是一个结构体,存放着文件的各种属性。

struct inode
{//文件大小//文件的inode编号//其他属性int blocks[15] //(0-11是直接索引,12-15是间接索引)
}
  • inode与文件名的关系:我们使用文件名去寻找文件,但是linux其实并不认识文件名,它只认识inode号,因此,在每个目录下面<文件名,inode>都有着对映的键值对,可以帮助转化成inode。
  • 目录也是文件,也有ionde号,也有data Block。
    因此对于一个目录,进入目录需要X(执行)权限,创建文件需要W(写)权限(要写数据块),显示文件名与属性r(读)权限(要读数据块)。

创建文件过程:首先os申请一个inode号,并且为之分配一个数据块,然后更新inode表。完成之后,更新目录的data block。

发现系统还有空间,为什么不能创建文件?

因为inode和data block是固定的。可能是没有ionde号了。

软硬链接

  • 硬链接是通过inode引用另外一个文件,引用计数+1,inode号相同,相当于共享一个inode。
  • 软链接是通过名字引用另外一个文件,引用计数不变,新inode号,相当于一个新的inode号指向老的inode号,相当于快捷方式。

在这里插入图片描述

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

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

相关文章

Linux网络配置与抓包工具介绍

目录 一、配置命令 1. ifconfig 1.1 概述信息解析 1.2 常用格式 2. ip 2.1 ip link 数据链路层 2.2 ip addr 网络层 2.3 路由 3. hostname 3.1 临时修改主机名 3.2 永久修改主机名 4. route 5. netstat 6. ss 7. ping 8. traceroute 9. nslookup 10. 永久修…

UI5与后端的文件交互(一)

文章目录 前言一、RAP的开发1. 创建表格2. 创建CDS Entity3. 创建BDEF4. 创建implementation class5. 创建Service Definition和Binding6. 测试API 二、创建UI5 Project1. 使用Basic模板创建2. 创建View3. 测试页面及绑定的oData数据是否正确4. 创建Controller5. 导入外部包&am…

计算机体系结构期末复习流程大纲

1.存储器和cache 存储器的容量、速度与价格之间的要求是相互矛盾的&#xff0c;速度越快&#xff0c;没bit位价格越高&#xff0c;容量越大&#xff0c;速度越慢&#xff0c;目前主存一般有DRAM构成。 处理器CPU访问存储器的指标&#xff1a; 延迟时间&#xff08;Latency&am…

【算法】算法设计与分析 期末复习总结

第一章 算法概述 时间复杂度比大小&#xff0c;用代入法&#xff0c;代入2即可。求渐进表达式&#xff0c;就是求极限&#xff0c;以极限为O的括号&#xff1b;O是指上界&#xff0c;Ω是指下界&#xff0c;θ是指上下界相等&#xff0c;在这里&#xff0c;可以这样理解&#…

Influxdb2修改管理员密码

通过恢复管理员令牌来重置InfluxDB2管理员的密码 1.找到数据库的配置文件 一般为config.json 2.配置文件的的blod文件配置 3.在这个混合文本和二进制json文件中搜索已知的用户名或token之类的字符串。 例如&#xff1a; "id":"0bd73badf2941000","…

WEB 3D技术 three.js 线框几何体

本文 我们说一下 线框几何体 想将一个几何体 以线框形式展现 threeJS中 有两种类可以实现 第一种 WireframeGeometry 这种几何体 其实就类似于 将材质中的 wireframe 开启 这种方法 之前我们也用过 还有一种 就是 EdgesGeometry 边缘几何体 我们先将代码写成这样 import .…

关于kthread_stop的疑问(linux3.16)

线程一旦启动起来后&#xff0c;会一直运行&#xff0c;除非该线程主动调用do_exit函数&#xff0c;或者其他的进程调用kthread_stop函数&#xff0c;结束线程的运行。 之前找销毁内核线程的接口时&#xff0c;发现了kthread_stop这个接口。网上说这个函数能够销毁一个内核线程…

Java中的IO流

在Java中&#xff0c;I/O&#xff08;输入/输出&#xff09;流用于处理与输入和输出相关的操作。Java的I/O流按照数据处理的不同方式分为两大类&#xff1a;字节流和字符流。每个类别又分为输入流和输出流。以下是Java中常用的I/O流及其继承关系&#xff1a; 字节流&#xff0…

批量剪辑方法:掌握视频剪辑技巧,按指定时长轻松分割视频

在视频制作和编辑过程中&#xff0c;经常要批量处理和剪辑大量的视频片段。学会批量剪辑方法可以提高工作效率&#xff0c;还可以使视频编辑更加准确和高效。下面来看下云炫AI智剪如何按指定时长轻松分割视频的批量剪辑方法。 分割后的视频文件效果&#xff0c;已分割分段的视…

业界首款PCIe 4.0/5.0多通道融合接口SSD技术解读

之前小编写过一篇文章劝大家不要碰PCIe 5.0 SSD&#xff0c;详细内容&#xff0c;可以再回顾下&#xff1a; 扩展阅读&#xff1a;当下最好不要入坑PCIe 5.0 SSD 如果想要进一步了解PCIe 6.0&#xff0c;欢迎点击阅读&#xff1a; 浅析PCIe 6.0功能更新与实现的挑战 PCIe 6.…

云卷云舒:【实战篇】云主机/虚拟机迁移

1. 简介 用户原有业务通过不同版本型号、不同操作系统的主机承载&#xff0c;形式上包括物理服务器、虚拟机、公有云主机等。随着业务不断扩张&#xff0c;需要将其业务云化转型&#xff0c;必须保证上云过程数据完整&#xff0c;业务平滑过度。 如果将所有业务系统都重新部署…

教你如何将本地虚拟机变成服务器,供其它电脑访问

场景&#xff1a;最近在做数据仓库的作业&#xff0c;需要团队协作&#xff0c;买不起阿里云服务器&#xff0c;所以想到能不能将我本地机上的虚拟机变成服务器&#xff0c;供其它同学的电脑访问。在虚拟机上安装hadoop和hive&#xff0c;然后同学机子上安装kettle进行连接。最…

Java 反射(一)

反射 1.反射的介绍 1.反射机制允话程序在执行期间借助于Refelction API取得任何类的信息&#xff08;比如成员变量&#xff0c;构造器&#xff0c;成员方法等&#xff09;并能操作对象的属性及方法&#xff0c;反射在设计模式和框架底层都会用到 2.加载完类之后&#xff0c;在…

可狱可囚的爬虫系列课程 08:新闻数据爬取实战

前言 本篇文章中我带大家针对前面所学 Requests 和 BeautifulSoup4 进行一个实操检验。 相信大家平时或多或少都有看新闻的习惯&#xff0c;那么我们今天所要爬取的网站便是新闻类型的&#xff1a;中国新闻网&#xff0c;我们先来使用爬虫爬取一些具有明显规则或规律的信息&am…

【Redis-04】Redis命令在客户端与服务器之间的执行流程

Redis本质上是一个数据结构服务器&#xff0c;支持键值对类型存储的内存管理系统&#xff0c;可以用作数据库、缓存和消息中间件&#xff0c;在我日常的开发中&#xff0c;基本上使用redis作为缓存中间件。 在Redis中有两个重要的角色&#xff0c;一个是服务器server&#xff0…

Adding Conditional Control to Text-to-Image Diffusion Models——【论文笔记】

本文发表于ICCV2023 论文地址&#xff1a;ICCV 2023 Open Access Repository (thecvf.com) 官方实现代码&#xff1a;lllyasviel/ControlNet: Let us control diffusion models! (github.com) Abstract 论文提出了一种神经网络架构ControlNet,可以将空间条件控制添加到大型…

性能分析与调优: Linux 监测工具的数据来源

目录 一、实验 1.环境 2. proc目录 3. sys目录 4.netlink 5.tracepoint 6.kprobes 7. uprobes 二、问题 1.systemd如何查看启动时间 2.CentOS与Ubuntu如何安装bpftrace 3.snap有哪些常用的命令 4.snap如何安装store 5.如何列出使用bpftrace的OpenJDK USDT探针 一…

显示管理磁盘分区 fdisk

显示管理磁盘分区 fdisk fdisk是用于检查一个磁盘上分区信息最通用的命令。 fdisk可以显示分区信息及一些细节信息&#xff0c;比如文件系统类型等。 设备的名称通常是/dev/sda、/dev/sdb 等。 对于以前的设备有可能还存在设备名为 /dev/hd* (IDE)的设备&#xff0c;这个设…

回顾2023编程之旅

一、前言 看在给了我一个博客专家的份上就继续写写博客&#xff0c;实事求是的讲如果是工作之余去总结csdn写写技术博客&#xff0c;还想混个专家什么的&#xff0c;真的是精力不够。因为里面的灌水的实在太多&#xff0c;比不过的&#xff0c;写这个玩意必须得淡泊名利才能悠然…

【PostgreSQL在线创建索引(CIC)功能的锁分析以及使用注意】

前一篇文章提到了普通创建索引会阻塞DML操作 PostgreSQL创建索引的锁分析和使用注意 而PostgreSQL里可以使用create index concurrently 在线创建索引(CIC)功能&#xff0c;降低创建索引在表上申请的锁的级别&#xff0c;ShareUpdateExclusiveLock级别的锁和RowExclusiveLock…