Linux_文件IO

目录

一、库函数进行文件操作

1、fopen/fclose

2、fwrite 

3、追加方式-“a” 

4、fread 

5、三个默认文件流 

二、系统函数进行文件操作

1、open/close

2、write 

3、追加方式-“O_APPEND” 

4、read 

5、struct file结构体

6、文件描述符

6.1 struct file的引用计数 

7、查看文件描述符的值

8、验证文件描述符0、1、2 

结语


前言:

        IO是Input/Output的首字母缩写,表示输入和输出,在Linux下一切皆为文件,使用文件无非只有读和写两种状态,即读对应Input,写对应Output,构成Linux下的基础IO。而对一个文件进行读写操作的前提是使用库函数 、系统调用函数先打开文件,然后再进行一系列的文件操作,本文着重介绍这些接口的使用。

一、库函数进行文件操作

        c语言标准库给上层提供了大量的文件接口,通过这些接口上层就可以对文件进行操作了,最常用的接口如下。 

1、fopen/fclose

        在对文件进行读写操作前,首先需要使用fopen打开文件,fopen是c中标准库<stdio.h>里的函数,用于打开一个文件,并且在打开文件时就要规定该文件是用于读还是用于写,或者是用于可读可写。

        fopen函数格式如下:

FILE *fopen(const char *filename, const char *mode);
//filename表示打开文件的路径,默认路径是该进程所在的路径
//mode表示打开文件的模式:常用的有:r(可读),w(可写),a(追加写)int fclose(FILE *fp);
//关闭一个文件流

        fopen测试代码如下:

#include <stdio.h>int main()
{// 打开文件的路径和文件名,默认在当前进程的路径下新建一个文件FILE *fp = fopen("log.txt", "a");//a表示追加写if(fp == NULL){perror("fopen");return 1;}fclose(fp);return 0;
}

         测试结果:

        发现在进程fopen.c的路径下创建了一个log.txt文件。

2、fwrite 

        fwrite将缓冲区内的数据输出至打开的文件中,该函数的格式如下:

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
//ptr表示指向要写入文件的缓冲区
//size表示从缓冲区内写入文件的数据的大小(单位字节)
//count表示写入多少个size字节至文件中,比如size是3,count是3,则从缓冲区拿9个字节
//stream表示写入的文件流//写入成功时返回count的值,写入失败返回小于(或不等于)count的数。

         fwrite测试代码(注意fopen的打开模式是“w”):

#include <stdio.h>
#include <string.h>int main()
{// 打开文件的路径和文件名,默认在当前进程的路径下新建一个文件FILE *fp = fopen("log.txt", "w");//此处要变成wif(fp == NULL){perror("fopen");return 1;}const char *message = "abcd\n";//定义输出缓冲区fwrite(message, strlen(message), 1, fp);fclose(fp);//sleep(1000);return 0;
}

        测试结果:

        从结果来看,abcd正常的写入到文件log.txt当中并且换行,所以可以理解现在log.txt中的内容是abcd+\n。


        更改上述代码中的缓冲区内容其他代码不变,并且重新执行该代码,观察log.txt中的内容是否发生变化:

const char *message = "该文件中只有这一句\n";

        测试结果:

        发现原先的内容abcd+\n被新内容覆盖了。原因就是fopen中“w“模式在写入前,会把文件内的内容全部清空,因此当重新调用fopen时会把目标文件的内容清空,所以若想保留文件中的内容对文件进行输出数据,要将fopen中的选项改成”a”追加选项。

3、追加方式-“a” 

        选项a会保留文件的内容,并且把数据输出在文件的末尾处:

#include <stdio.h>
#include <string.h>int main()
{// 打开文件的路径和文件名,默认在当前进程的路径下新建一个文件FILE *fp = fopen("log.txt", "a");//此处是a,表示追加写if(fp == NULL){perror("fopen");return 1;}const char *message = "追加写入\n";fwrite(message, strlen(message), 1, fp);fclose(fp);//sleep(1000);return 0;
}

         运行结果:

4、fread 

        以上是将缓冲区内的数据输出至文件中,fread则是从文件中输入数据至缓冲区内,然后通过打印缓冲区将文件的内容显示到屏幕上。 

        fread格式如下:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
//ptr指向缓冲区的指针
//size表示从文件中读取的每个元素的大小(单位字节)
//nmemb表示希望从文件中读取nmemb个size的内容
//stream表示读取的文件流//返回值表示最终读取的有效元素个数,读取失败返回-1,读到文件末尾返回0

        fread测试代码(注意fopen中选项要改成“r”):

#include <stdio.h>
#include <string.h>int main()
{// 打开文件的路径和文件名,默认在当前进程的路径下新建一个文件FILE *fp = fopen("log.txt", "r");//此处是a,表示追加写if(fp == NULL){perror("fopen");return 1;}char message[128];//-1的目的是预留一个位置给\0,否则读取的数据塞满了message数组,则后续手动//添加\0会导致越界访问size_t n = fread(message,sizeof(char),sizeof(message)-1,fp);if(n>0){//printf("n=%d",n);message[n] = 0;printf("%s\n",message);}fclose(fp);//sleep(1000);return 0;
}

         运行结果:

5、三个默认文件流 

        c程序启动时会默认打开三个标准输入输出文件流,分别是stdin(键盘文件)、stdout(显示器文件)、stderr(显示器文件),其中stdout和stderr的区别是:stdout是标准输出流,stderr是标准错误流,后者通常用于打印一些错误信息,其中printf默认从stdout标准输出打印。 

        将上述代码中fwrite的目标文件流换成stdout,则缓冲区内的信息会打印在屏幕上:

#include <stdio.h>
#include <string.h>int main()
{// 打开文件的路径和文件名,默认在当前进程的路径下新建一个文件FILE *fp = fopen("log.txt", "a");//此处是a,表示追加写if(fp == NULL){perror("fopen");return 1;}const char *message = "追加写入\n";fwrite(message, strlen(message), 1, stdout);//此处不再是fp而是stdoutfclose(fp);//sleep(1000);return 0;
}

        测试结果:

二、系统函数进行文件操作

        文件是存储在磁盘上的,而磁盘属于硬件设备,因此访问文件的本质就是让计算机访问硬件设备,访问硬件设备的权力只有操作系统有,所以可以推断标准库提供的大量文件操作函数的底层是调用系统函数的,因此我们可以直接调用系统函数来实现操作文件。

1、open/close

        open/close对标fopen/fclose,也有着创建文件和关闭文件的作用,只不过open更偏向底层一些,具体格式如下:

#include <unistd.h>int open(const char *pathname, int flags, mode_t mode);
//pathname表示路径,即创建或打开文件的所在路径
//flag是一个整形,但是他可以表示打开文件的多种模式,对标fopen中“w”,“a”选项,falg也是一个选项
//mode表示新建文件的初始权限,用十进制来表示权限//返回值是一个整形,表示的是文件描述符,而不是fopen的文件指针,错误返回-1并设置错误码errorint close(int fildes);
//关闭一个文件描述符

        从open的格式可以发现,flag比较特殊,因为他是一个整形而不是字符串的形式,所以系统规定了几个特殊的宏,这些宏才是表示文件可读、可写的各种选项,常用的宏如下:

  • O_RDONLY:以只读模式打开文件,对标“r”(必填之一)。
  • O_WRONLY:以只写模式打开文件,对标“w”(必填之一)。
  • O_RDWR:以读写模式打开文件,对标“rw”。
  • O_CREAT:如果文件不存在,则创建新文件。通常需要与O_WRONLYO_RDWR一起使用。
  • O_APPEND:每次写入都在文件的末尾添加数据,对标“a”。
  • O_TRUNC:如果文件已存在,并以写方式打开,则将其内容清空。

        并且open的返回值是一个整形,表示文件描述符,和fopen不一样,但是该整形的用法和fopen的文件指针是一样的,即在该进程下,用文件描述符表示访问一个文件的入口


         open测试代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{//0666 = rw- rw- rw-int fd = open("log.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);if(fd < 0)//当文件描述符小于0则说明打开失败{printf("open file error\n");return 1;}close(fd);//关闭文件描述符return 0;
}

         运行结果:

         从运行结果来看,确实成功创建了文件log.txt,但是仔细观察发生log.txt的权限不是0666,而是0664,原因就是我们创建文件的最终权限=起始权限&(~umask),而umask默认值是0002,所以导致最后一个权限的中间bit位一定会是0,因此正确设置文件的初始权限,则要把umask的值设为0。

        在上述代码调用open前加上

umask(0);

        再次测试上述代码:

2、write 

        write的作用自然不用多说,和fwrite是一样的,因为fwrite底层调用的就是write,wrtie格式如下:

#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);
//fd表示目标文件的文件描述符
//buf表示缓冲区
//count表示从缓冲区内读取的字节数(对标fwrite的size*count)//成功写入时返回写入的字节数,失败时返回-1

         测试write的代码如下:

#include <stdio.h>
#include <unistd.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|O_TRUNC, 0666);if(fd < 0){printf("open file error\n");return 1;}const char message[] = "hello world\n";//自定义缓冲区ssize_t poi = write(fd, message, sizeof(message)-1);//无需把\0也写进文件中if (poi == -1) {  perror("write");  return -1;} close(fd);return 0;
}

         测试结果:


        注意:因为open的打开模式加上了O_TRUNC,所以每次调用open时会把log.txt的内容清空再打开,若open模式中没有O_TRUNC,则每次调用open时不会清空文件内容,但是是从文件是最开始进行覆盖式的写入,具体代码如下:

#include <stdio.h>
#include <unistd.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);//没有O_TRUNCif(fd < 0){printf("open file error\n");return 1;}const char message[] = "zzz\n";//自定义缓冲区ssize_t poi = write(fd, message, sizeof(message)-1);//无需把\0也写进文件中if (poi == -1) {  perror("write");  return -1;} close(fd);return 0;
}

        测试结果:

        从结果看到,原先内容的前四个字节被覆盖了。 

3、追加方式-“O_APPEND” 

         若想实现系统函数open的追加方式,则在模式中添加O_APPEND宏即可,示例代码如下:

#include <stdio.h>
#include <unistd.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|O_APPEND, 0666);//没有O_TRUNCif(fd < 0){printf("open file error\n");return 1;}const char message[] = "追加语句\n";//自定义缓冲区ssize_t poi = write(fd, message, sizeof(message)-1);//无需把\0也写进文件中if (poi == -1) {  perror("write");  return -1;} close(fd);return 0;
}

         运行结果:

        不过值得注意的是: O_APPEND是一种方式并不包含写模式,所以使用O_APPEND时必须是写模式,否则连数据都无法写入文件中更别提追加了。

4、read 

         read是系统提供的系统函数,他的作用是读取文件中的内容至输入缓冲区内,和fread的作用是一样的,具体格式如下:

#include <unistd.h>  ssize_t read(int fd, void *buf, size_t count);
//fd表示文件描述符
//buf表示存放文件内容的缓冲区
//count表示从文件中读取多少字节的数据//读取成功时返回值表示读取到有效字节的个数,读取失败返回-1,读到文件末尾返回0

        测试read的代码如下(注意将open的打开模式设为O_RDONLY或O_RDWR):

#include <stdio.h>
#include <unistd.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_RDONLY,0666);if(fd < 0){printf("open file error\n");return 1;}char message[128];//自定义缓冲区ssize_t poi =read(fd,message,sizeof(message)-1);//预留\0的位置if(poi==-1){perror("read");return -1;}message[poi] = 0;printf("%s",message);close(fd);return 0;
}

        运行结果:

5、struct file结构体

        操作系统对新打开文件会创建一个结构体(struct file)来管理该文件,并且一个文件只有一个struct file,因为涉及到新打开的文件和新关闭的文件,所以关闭文件的时候会把该结构体删除,那么此时就要对管理文件的结构体进行数据结构化,因为要方便对其进行增删查改,所以有了文件管理链表,具体示意图如下:

        描述文件的结构体struct file有了,那么底层是如何找到struct file的呢?答案是通过文件描述符找到的。

6、文件描述符

        要想访问文件的前提是调用open函数打开文件,并且open函数会返回该文件的文件描述符,所以打开一个文件只能是在进程中完成,因为只有进程中才能调用函数(因此文件描述符肯定是存放在进程PCB中)。在一个进程内访问一个文件必须通过该文件的文件描述符,文件描述符在单个进程中具有唯一性。 

        PCB、文件描述符、struct file关系图如下:

        通过上图可以发现文件描述符就是PCB中的一个结构体里的指针数组的下标,并且每个进程都会有属于自己是struct file_struct结构体,这也是为什么进程间的文件描述符是独立的。 

6.1 struct file的引用计数 

        打开文件会返回一个文件描述符,关闭一个文件描述符会关闭了一个文件吗?

        答案:不会,因为一个进程打开的文件,别的进程也许也打开了这个文件,比如一个进程open了显示器文件,则open函数会返回一个文件描述符给该进程,让该进程可以通过这个文件描述符访问显示器,即打印数据在显示器上,但是当该文件关闭了该文件描述符,如果直接把显示器文件关闭了,则其他的进程就无法打印数据到显示器上了,这不符合逻辑,因此当多个进程使用同一份文件时,进程关闭自己的文件描述符不会直接关闭文件管理链表上的文件

        因为一个文件只有一个struct file,所以大量的进程打开同一个文件时,struct file结构体中有一个专门记录进程个数的引用计数,只有当引用计数变成0时代表当前没有进程访问该文件了,就会把文件的结构体struct file从文件管理链表中删除。

7、查看文件描述符的值

        以下代码在一个进程内多次open文件,然后打印open返回的值,并观察其中的逻辑:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{umask(0); //一次创建四个文件int fd1 = open("log1.txt", O_WRONLY|O_CREAT|O_APPEND, 0666);int fd2 = open("log2.txt", O_WRONLY|O_CREAT|O_APPEND, 0666);int fd3 = open("log3.txt", O_WRONLY|O_CREAT|O_APPEND, 0666);int fd4 = open("log4.txt", O_WRONLY|O_CREAT|O_APPEND, 0666);if(fd1 < 0){printf("open file error\n");return 1;}//打印这四个文件描述符观察其逻辑printf("fd1: %d\n", fd1);printf("fd2: %d\n", fd2);printf("fd3: %d\n", fd3);printf("fd4: %d\n", fd4);return 0;
}

         运行结果:

        从结果发现,打开的第一个文件返回的文件描述符是从3开始,之后的文件描述符按顺序往下走,原因就是上文提到的c程序刚开始会默认打开三个文件流,分别是stdin、stdout、stderr,这三个文件流刚好就是0、1、2,所以我们在程序中open文件的文件描述符是从3开始的。 

8、验证文件描述符0、1、2 

        文件描述符0、1、2对应三个文件流stdin、stdout、stderr,所以当使用write接口时,可以把文件描述符1传给write,这样就可以在屏幕上看到输出的信息了。

        示例代码:

#include <stdio.h>
#include <unistd.h>int main()
{const char message[] = "hello world\n";//自定义缓冲区ssize_t poi = write(1, message, sizeof(message)-1);//此处fd传的1if (poi == -1) {  perror("write");  return -1;} return 0;
}

        运行结果:


        并且可以通过stdin、stdout、stderr来验证他们对应的文件描述符是0、1、2,因为stdin、stdout、stderr是c程序启动时默认打开的文件流所返回的文件指针,所以该文件指针指向的文件结构体FILE肯定封装了底层的0、1、2,因此肯定通过stdin、stdout、stderr三个文件指针来找到底层的文件描述符并打印出来。示例代码如下:

#include <stdio.h>int main()
{printf("stdin->fd: %d\n", stdin->_fileno);printf("stdout->fd: %d\n", stdout->_fileno);printf("stderr->fd: %d\n", stderr->_fileno);return 0;
}

        测试结果:

        所以可以得出一个很重要的结论:c程序默认打开三个文件流的底层逻辑是进程会默认打开三个文件描述符0、1、2。 

结语

        以上就是关于文件IO的讲解,理解文件IO的首要工作是理解输入和输出的概念,常常把write写入数据至文件这个过程看成是输出,把read从文件中读取数据看成是输入,并且清楚理解文件描述符的意义,以及他和文件指针的关系。

         

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

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

相关文章

Pyqt QCustomPlot 简介、安装与实用代码示例(一)

目录 简介安装实用代码示例带有填充的简单衰减正弦函数及其红色的指数包络线具有数据点的 sinc 函数、相应的误差条和 2--sigma 置信带几种散点样式的演示展示 QCustomPlot 在设计绘图方面的多功能性 结语 所有文章除特别声明外&#xff0c;均采用 CC BY-NC-SA 4.0 许可协议。转…

数学-奇异值

有点名词党 奇异值的计算通常涉及矩阵的奇异值分解Singular Value Decomposition, SVD。奇异值分解是将一个矩形矩阵 ( A ) 分解为三个矩阵的乘积&#xff1a; [ A U ΣVT] 其中&#xff1a; - ( U ) 是一个 ( m m ) 的正交矩阵&#xff0c;它的列向量是 ( A AT) 的特征向…

课程标准包括哪些内容?

老师们常常会思考&#xff1a;课程标准究竟包含哪些要素&#xff1f;课程标准不仅仅是一系列冷冰冰的条条框框&#xff0c;而是活生生的指导原则&#xff0c;引领教学实践&#xff0c;激发学生的潜能。 课程标准&#xff0c;简而言之&#xff0c;是对学习成果的期望和要求的明确…

Starlink全系卫星详细介绍,波段频谱、激光星间链路技术、数据传输速率等等

Starlink全系卫星详细介绍&#xff0c;波段频谱、激光星间链路技术、数据传输速率等等。 Starlink是SpaceX公司开发的一个低轨道&#xff08;LEO&#xff09;卫星网络系统&#xff0c;旨在为全球用户提供高速宽带互联网服务。截至2024年6月&#xff0c;Starlink已经发射并运行…

rknn转换后精度差异很大,失真算子自纠

下面是添加了详细注释的优化代码&#xff1a; import cv2 import numpy as np import onnx import onnxruntime as rt from onnx import helper, shape_inferencedef get_all_node_names(model):"""获取模型中所有节点的名称。参数:model (onnx.ModelProto): O…

wordpress站群搭建3api代码生成和swagger使用

海鸥技术下午茶-wordpress站群搭建3api代码生成和swagger使用 目标:实现api编写和swagger使用 0.本次需要使用到的脚手架命令 生成 http server 代码 goctl api go -api all.api -dir ..生成swagger文档 goctl api plugin -plugin goctl-swagger"swagger -filename st…

【Kafka】Kafka Broker工作流程、节点服役与退役、副本、文件存储、高效读写数据-08

【Kafka】Kafka Broker工作流程、节点服役与退役、副本、文件存储、高效读写数据 1. Kafka Broker 工作流程1.1 Zookeeper 存储的 Kafka 信息1.2 Kafka Broker总体工作流程1.2.1 Controller介绍 1.3 Broker 重要参数 2. 节点服役与退役3. Kafka副本 1. Kafka Broker 工作流程 …

Python 数据可视化 散点图

Python 数据可视化 散点图 import matplotlib.pyplot as plt import numpy as npdef plot_scatter(ref_info_dict, test_info_dict):# 绘制散点图&#xff0c;ref横&#xff0c;test纵plt.figure(figsize(80, 48))n 0# scatter_header_list [peak_insert_size, median_insert…

深入探索C++中的AVL树

引言 在数据结构和算法的世界里&#xff0c;平衡二叉搜索树&#xff08;Balanced Binary Search Tree, BST&#xff09;是一种非常重要的数据结构。AVL树&#xff08;Adelson-Velsky和Landis发明的树&#xff09;就是平衡二叉搜索树的一种&#xff0c;它通过自平衡来维护其性质…

支付宝推出NFC(近场通信)碰一碰支付功能

近日&#xff0c;支付宝推出NFC&#xff08;近场通信&#xff09;碰一碰支付功能&#xff0c;支持iPhone、安卓手机。NFC支付早已不是新事物&#xff0c;从二维码支付重回NFC支付&#xff0c;支付宝能撬动市场吗&#xff1f; 根据网友反馈&#xff0c;目前支付宝正在上海静安大…

node版本过高出现ERR_OSSL_EVP_UNSUPPORTED错误

错误原因&#xff1a; 新版本的nodejs使用的openssl和旧版本不同&#xff0c;导致出错 解决方法&#xff1a; 1.将node版本重新换回16.x 2 windows 下 在package.json文件下添加set NODE_OPTIONS--openssl-legacy-provider && "scripts": {"dev"…

车辆轨迹预测系列 (二):常见数据集介绍

车辆轨迹预测系列 (二)&#xff1a;常见数据集介绍 文章目录 车辆轨迹预测系列 (二)&#xff1a;常见数据集介绍1、NuScenes (2020)&#xff1a;1、下载2、说明 2、Waymo Open Dataset (2020)&#xff1a;1、介绍2、概述3、下载4、教程5、参考 3、Lyft Level 5 (2020)&#xff…

如何把期末成绩发给家长?

期末的脚步越来越近&#xff0c;又到了头疼成绩怎么群发给家长的时候了&#xff0c;别担心&#xff0c;期末成绩群发秘籍来帮忙&#xff0c;让我们一起完成这项任务&#xff01; 1. 邮件VS短信 首先得选个合适的沟通方式。邮件正式&#xff0c;适合详细说明&#xff1b;短信快…

数据仓库的实际应用示例-广告投放平台为例

数据仓库的数据分层通常包括以下几层&#xff1a; ODS层&#xff1a;存放原始数据&#xff0c;如日志数据和结构化数据。DWD层&#xff1a;进行数据清洗、脱敏、维度退化和格式转换。DWS层&#xff1a;用于宽表聚合值和主题加工。ADS层&#xff1a;面向业务定制的应用数据层。…

一个自定义流程的平台

脚本语言使用的是C#&#xff0c;当用户发布一个新的流程时&#xff0c;会把C#的脚本编译成dll&#xff0c;然后添加到微服务中&#xff0c;因为有了硬编译&#xff0c;所以执行速度是非常快的。逻辑脚本支持调试&#xff0c;可以断点和逐行调试。平台提供了调试工具&#xff0c…

DevEco鸿蒙开发请求网络交互设置

首先&#xff0c;在鸿蒙项目下config.json中找到module项&#xff0c;在里面填写"reqPermissions": [{"name": "ohos.permission.INTERNET"}] 在页面对应js文件内&#xff0c;填写import fetch from system.fetch;。 GET和POST区别 GET将表单数…

人工智能--搭建人工神经网络

欢迎来到 Papicatch的博客 文章目录 &#x1f349;引言 &#x1f349;神经元与感知器 &#x1f348;神经元&#xff08;Neuron&#xff09; &#x1f348;感知器 &#x1f349;损失函数与梯度下降算法 &#x1f348;损失函数 &#x1f348;梯度下降算法 &#x1f349;…

如何解决跨境传输常见的安全及效率问题?

在当今全球化的商业版图中&#xff0c;企业为了拓展国际市场和增强竞争力&#xff0c;跨境传输数据已成为一项不可或缺的业务活动。合格的数据跨境传输方案&#xff0c;应考虑以下要素&#xff1a; 法律合规性&#xff1a;确保方案符合所有相关国家的数据保护法律和国际法规&am…

ffmpeg音视频开发从入门到精通——ffmpeg下载编译与安装

音视频领域学习ffmpeg的重要性 音视频领域中ffmpeg的广泛应用&#xff0c;包括直播、短视频、网络视频、实时互动和视频监控等领域。掌握FM和音视频技术可以获得更好的薪酬。 学习建议音视频学习建议与实战应用 音视频处理机制的学习&#xff0c;需要勤加练习&#xff0c;带…

永磁同步电机驱动死区补偿

1 死区效应及补偿 1. 1 死区效应 在本文的电机控制嵌入式系统中,逆变器为三 相电压型桥式逆变电路,如图 1 所示。 在理想状态 下,上桥臂和下桥臂的控制信号满足互补通断原则, 即上桥臂开通时,下桥臂关断,反之亦然。 而在实际 应用中,开关管的通断需要一定的开通时…