最新资讯

  • 【Linux篇】基础IO - 文件描述符的引入

【Linux篇】基础IO - 文件描述符的引入

2025-04-25 18:59:54 1 阅读

📌 个人主页: 孙同学_
🔧 文章专栏:Liunx
💡 关注我,分享经验,助你少走弯路!


文章目录

    • 一. 理解文件
      • 1.1 侠义理解
      • 1.2 广义理解
      • 1.3 文件操作的归类认知
      • 1.4 系统角度
    • 二. 回顾C语言文件接口
      • 2.1 打开文件
      • 2.2 对文件进行写入
      • 2.3 输出信息到显示器,有哪些方法
      • 2.4 stdin & stdout & stderr
      • 2.5 打开文件的方式
    • 三. 系统文件I/O
      • 3.1 位图传递标志位
      • 3.2 open
      • 3.3 write
      • 3.4 read
    • 四. 访问文件的本质
      • 4.1 文件描述符

一. 理解文件

我们以前就说过 文件 = 文件内容 + 文件属性

1.1 侠义理解

  • 文件是在磁盘上的,磁盘本质上是个外设,我们访问文件其实就是在系统和磁盘上进行IO
  • 磁盘是永久性的存储介质,文件在磁盘上的存储是永久性的
  • 对文件的所有操作,本质上是对外设的输入输出 简称 IO

1.2 广义理解

  • Linux下一切皆文件(键盘,显示器,网卡,磁盘… )

1.3 文件操作的归类认知

  • 对于0KB的空文件,是占据磁盘的空间的
  • 文件 = 文件内容 + 文件属性
  • 所有对文件的操作本质上是对文件内容和文件属性的操作

1.4 系统角度

  • 对文件的操作本质上是进程对文件的操作
  • 磁盘的管理者是操作系统
  • 文件的读或写本质上不是通过 C语言/C++的库函数来操作的(这些库函数只是为用户提供方便),而是通过文件相关的系统调用接口实现的

文件

  1. “内存级(被打开)”文件
  2. 磁盘级文件

二. 回顾C语言文件接口

2.1 打开文件

// 文件打开接口
FILE *fopen(const char *path, const char *mode);

  • path:表示要打开文件的路径,或者文件名,只有文件名而没有路径表示打开当前路径下的文件。
  • mode:表示打开的方式,比如只读r,只写w,追加a等。

📌 Tips: 我们之前介绍的重定向,>本质上就对应使用的是w选项,>>本质上就对应使用的是a选项。

2.2 对文件进行写入

#include

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

	return 0;
}

打开的myfile文件在哪个路径下呢?

  • 在程序的当前路径下
  • 那系统怎么知道程序的当前路径在哪里呢?
    可以使用ls /proc/[进程id] -l命令查看当前正在运行进程的信息:

  • cwd:进程当前的工作路径
  • exe:指向启动当前进程的可执行文件(完整路径)的符号链接。

2.3 输出信息到显示器,有哪些方法

  • printf()
  • fprintf()
  • fwrite()


    当我们向显示器打印本质上就是向显示器文件写入,Linux下一切皆文件

2.4 stdin & stdout & stderr

  • c语言会默认打开三个输入输出流,分别是stdin,stdout,stderr
  • 这三个流的类型都是FILE*


    为什么要帮我们把这几个流自动打开呢?
    我们传统上写的程序是做数据处理的

2.5 打开文件的方式

  1. w的方式打开文件时,文件首先会被清空,然后从0开始写
  2. 我们以前说过的重定向,比如echo aaaaa > log.txt,把打印到显示器上的内容写入文件里,前提是我们先得把文件打开。我们的输出重定向>log.txt为什么会把文件内容清空呢?因为我们输出重定向第一步要打开文件,而打开文件,而打开文件第一步先要把文件清空
  3. a的方式打开文件,这种方式叫做追加,它一般写的时候会向文件结尾进行写入,不存在的话就创建它。>>叫做追加重定向,以a的方式进行写入本质上也是先要把文件打开,然后再进行写入。

  4. 当我们向文件里写入一段字符串时,我们需不需要在字符串后面加呢?答案是不需要,因为是c语言的规定,与我文件又有什么关系呢。

三. 系统文件I/O

我们对文件操作的是时候,文件是在磁盘上面的,而真正对文件进行操作的其实是操作系统,操作系统对磁盘文件进行读写访问,我们以前使用c语言对文件的访问其实是c语言封装了系统调用。比如说访问文件得先打开,那么就得先有open

flags有众多选项O_RDONLY表示只读, O_WRONLY表示只写, O_RDWR表示读写,O_TRUNC表示

int open(const char *pathname,int flags,mode_t mode);

如果我们今天要打开一个文件,并且这个文件不存在要新建的话,就用上面的这个open,必须指定权限,如果不指定的话这个权限就是乱码。如果打开一个已经存在的文件,就用两个参数的。

open的返回值:如果打开成功的话返回一个新的文件描述符,如果失败的话-1被返回,并且错误码就被设置了。

flags是一种整形标志位,一共有32个bit位,,如果用O_RDONLY这种选项直接传参的话会很麻烦,所以选用位图的方式来传递。

3.1 位图传递标志位

#include

#define ONE_FLAG    (1<<0)// 000000....00000001
#define TWO_FLAG    (1<<1)// 000000....00000010
#define THREE_FLAG  (1<<2)// 000000....00000100
#define FOUR_FLAG   (1<<3)// 000000....00001000

void Print(int flags)
{
    if(flags & ONE_FLAG)
    {
        printf("One!
");
    }
    if(flags & TWO_FLAG)
    {
        printf("Two!
");
    }
    if(flags & THREE_FLAG)
    {
        printf("Three!
");
    }
    if(flags & FOUR_FLAG)
    {
        printf("Four!
");
    }



 }

int main()
{
    Print(ONE_FLAG); //打印one
    printf("
");
    Print(ONE_FLAG | TWO_FLAG); //打印one two
    printf("
");
    Print(ONE_FLAG | TWO_FLAG | THREE_FLAG);//打印one two three
    printf("
");
    Print(ONE_FLAG | TWO_FLAG | THREE_FLAG | FOUR_FLAG);//打印one two three four
    printf("
");

    return 0;
}


3.2 open

我们open打开文件的时候绝对相对路径都可以,因为在哪个路径下创建文件是由进程决定的,进程记录了自己的cwd,说明我们新建文件是在指定路径下建还是在其他路径下建和cd,fopen都没有关系,它是系统的行为。
我们接下来验证一下log.txt它默认会在当前路径下去创建,因为它进程的路径就在当前路径下。


我们对文件进行写入write接口

#include 

ssize_t write(int fd, const void *buf, size_t count);
  • 第一个参数:open的返回值,这个返回值叫文件描述符
  • 第二个参数: 是我们要写入的buffer
  • 第三个参数: 是我们要写的数据的长度,返回值是实际写入的长度。写入失败返回-1
#include
#include
#include
#include
#include
#include

int main()
{
    umask(0);//在新建文件之前将umask权限眼掩码设置为0
    int fd = open("log.txt",O_CREAT | O_WRONLY,0666);//不存在就创建,而且以写入的方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//进程的退出码设为1
    }

    printf("fd = %d/n",fd);
    const char *msg = "hello world
";//定义一个字符串
    int cnt = 5;
    while(cnt)
    {
        write(fd,msg,strlen(msg));//向指定文件描述符里写,写的内容是msg,写的长度
        //我们在写入时是当做字符来写,所以这里不需要strlen(msg)+1,因为是c语言规定的,如果写的话在我们的文件中就会出现@^乱码现象
        cnt--;
    }
    

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


当我们把要写的内容该为abcd并且只让它写一行。


现象是在我们往文件里写的时候应当是先清空再进行写入,而现在是覆盖写,文件内原来的内容并没有清空,为什么没有清空呢?答案是我们再创建文件的时候,只填了创建写入,而并没有要清空

所以我们加上O_TRUNC


💦结论:如果我们要打开文件,并且将它清空,若要用系统级的函数,我们就需要传递这几个标志位。

清空并写入:

int fd = open("log.txt",O_CREAT | O_WRONLY | O_TRUNC,0666);

如果O_CREAT(不存在就新建),O_WRONLY(以只写入的方式),O_TRUNC(清空)
追加并写入:

int fd = open("log.txt",O_CREAT | O_WRONLY | O_APPEND,0666);

所以C语言中的fopen中的w选项和a选项就会被分别转化为上面的那样。

3.3 write

write这个接口在写的时候参数不是char*,而是void*

ssize_t write(int fd, const void *buf, size_t count);

说明write在进行写入的时候,进行二进制写入也可以,做字符串写入也可以。

文本写入 vs 二进制写入
我们在往显示器上打印12345的时候是往显示器打印的是1字符2字符3字符4字符和5字符。而不是一万两千三百四十五。

📌小tips: 我们往显示器上打印和我们往文件里写入其实是一摸一样的,因为Linux下一切皆文件。

我们往文件里以清空写的方式写入1234567

查看log.txt

我们会发现log.txt4个字节里面的内容是乱码,这是为什么呢?因为这种写入叫做二进制写入,在实际写的时候把a这个整形变量写到了文件里面,所以文件的大小是4字节,因为整数的大小是4字节,而我们写入的1234567不可显,它是把1234567这个二进制数字写在了磁盘上。而我们想看到的是1234567,那可怎么办呢?

a这个整形格式化处理成字符串,然后将字符串写入到要写的文件中。

此时的log.txt中就是1234567了。
💦结论: 在系统层面上并不存在所谓的文本写入和二进制写入,系统并不关心你写入的类型,文本写入还是二进制写入其实是语言层 提供的概念。所以我们在c语言中有fpus文本写入fwrie二进制写入,这两个底层最终调用的都是这个接口。

ssize_t write(int fd, const void *buf, size_t count);

格式化输入输出其实就是将内存里的二进制数据转成字符串,在使用write接口将数据写进去。所以格式化输入输出,文本式的写入全都是语言层的概念。这个格式化工作要么是语言来做,要么是我们自己来做。

3.4 read

 #include 

       ssize_t read(int fd, void *buf, size_t count);

  • 返回值:如果成功,则返回读的字节数(0表示文件结束),如果错误返回-1
  • 第一个参数:是open的返回值,这个返回值叫文件描述符
  • 第二个参数: 指向一段空间,该空间用来存储读取到的内容。

我们读取log.txt中的内容


四. 访问文件的本质

我们一次性打开四个文件,并观察它的fd

打出来的文件描述符是3,4,5,6问题是0,1,2去哪里了呢?

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

这三个叫做默认的文件流,因为它默认的把三个文件打开了,012已经被占了。
C语言中有三个标准输入,标准输出,标准错误的文件流

C++中也有标准输入(cin),标准输出cout,标准错误cerr的文件流

C语言中我们打开文件叫做FILE*,*是指针,可是FILE是什么呢?FILEC语言提供的一个结构体,它是被typedef出来的,结构体里包含了文件的属性。
OS接口层面上只认fd文件描述符,所以这个结构体里一定封装了文件描述符


所以我们以前学到的文件操作,在类型层面的文件对象FILE封装了文件描述符,在接口层面打开文件是封装了对应的选项。

所以任何语言,底层只认文件描述符,C语言/C++会把市面上的各种平台的代码各自实现一份,然后采用条件编译,代码裁剪的方式,把不同的系统需要的库编到不同的系统里,给用户提供的是同一个语言型接口,这样写出来的代码具有可移植性

要了解可移植性就需要知道不可移植性,不可移植性是由于平台不一样,平台不一样系统调用的接口不一样。

4.1 文件描述符

 操作系统要把被打开的文件管理起来,怎么管理呢?先描述,再组织

 创建一个进程的时候,首先在内核当中创建的了一个task_struct,我们称之为进程控制块。操作系统在打开文件时需要在内核当中创建一个数据结构struct file,打开很多文件就会创建很多的struct file,然后用指针连接起来。那么找一个文件的所有内容或者任何一个属性就都能通过struct file找到。也就是说未来想访问文件就只需要找到对应的struct file结构体队对象就可以了。
 在文件中,每一个文件的struct file都会提供一个文件级缓冲区,将来文件的内容就会加载到文件缓冲区当中,文件的属性会用来初始化我们的struct file以及将来的inode结构体。今天我们如果是想读取文件里面的内容,一定先是我们把文件打开,创建struct file结构体,通过file内部的指针操作找到文件缓冲区,然后操作系统把文件的内容给我们加载或者预加载到缓冲区里面,加载之后我们读写文件的本质就是从缓冲区里面把内容拷贝出去。
 可是在进程中怎么快速找到我们自己打开的文件呢?被连起来的文件有可能属于进程a,也有可能属于进程b,哪个文件是和你的进程相关的呢?在我们的进程的PCB当中,当一个进程被创建,除了地址空间页表,它还要创建一个struct files_struct文件描述符表,文件描述符表中包含一个数组,这个数组是可大可小的,一般的Linux系统是32或者64,在云服务器上它可以支持内核扩展,这个struct files_struct中还包含了其他属性,包括打开文件的个数,其他的一些属性信息。这个数组叫做struct file *fd array[],这是一个指针数组,在PCB中会存在一个struct files_struct *files指向文件描述符表。这个数组中放的就是这个进程打开的文件,把操作系统打开的struct file对象填充到我们数组对应的指定下标当中。此时那些进程有哪些文件就被关联起来了,建立被打开的文件和进程之间的映射关系。所以进程要访问任意一个被打开的文件就可以通过下标来访问了。
所以文件描述符的本质就是数组下标
 当我们的用户层在进行open调用的时候,就会在操作系统里创建一个新的struct file,然后在当前进程的文件描述符表里面找到一个没有被使用的下标,然后把struct file的地址填进去,此时进程和文件就关联了。下来读取数据(read)时要传fd,当前进程调用read,进程拿着fd去文件描述符中的数组中找,就能找到对应的文件,每一个文件都有对应的文件缓冲区,操作系统把磁盘中的内容预加载到缓冲区当中,然后把文件缓冲区当中的数据拷贝到用户层的buffer中。

文件描述符的分配原则:最小的没有被使用的作为新的fd分配给用户。


👍 如果对你有帮助,欢迎:

  • 点赞 ⭐️
  • 收藏 📌
  • 关注 🔔

本文地址:https://www.vps345.com/1032.html

搜索文章

Tags

PV计算 带宽计算 流量带宽 服务器带宽 上行带宽 上行速率 什么是上行带宽? CC攻击 攻击怎么办 流量攻击 DDOS攻击 服务器被攻击怎么办 源IP 服务器 linux 运维 游戏 云计算 python MCP javascript 前端 chrome edge 进程 操作系统 进程控制 Ubuntu ssh llama 算法 opencv 自然语言处理 神经网络 语言模型 阿里云 网络 网络安全 网络协议 ubuntu deepseek Ollama 模型联网 API CherryStudio fastapi mcp mcp-proxy mcp-inspector fastapi-mcp agent sse filezilla 无法连接服务器 连接被服务器拒绝 vsftpd 331/530 harmonyos 华为 开发语言 typescript 计算机网络 数据库 centos oracle 关系型 安全 分布式 flutter RTSP xop RTP RTSPServer 推流 视频 udp unity tcp/ip uni-app windows 微服务 springcloud ollama ai 人工智能 llm vim ide c++ php android java 面试 性能优化 jdk intellij-idea 架构 宝塔面板访问不了 宝塔面板网站访问不了 宝塔面板怎么配置网站能访问 宝塔面板配置ip访问 宝塔面板配置域名访问教程 宝塔面板配置教程 spring boot 后端 tomcat vue.js audio vue音乐播放器 vue播放音频文件 Audio音频播放器自定义样式 播放暂停进度条音量调节快进快退 自定义audio覆盖默认样式 pycharm pytorch 机器学习 ssl 前端框架 深度学习 YOLO 目标检测 计算机视觉 LDAP 智能路由器 外网访问 内网穿透 端口映射 docker 容器 adb nginx 监控 自动化运维 运维开发 WSL win11 无法解析服务器的名称或地址 django flask web3.py numpy asm live555 rtsp rtp Hyper-V WinRM TrustedHosts web安全 Kali Linux 黑客 渗透测试 信息收集 golang GaN HEMT 氮化镓 单粒子烧毁 辐射损伤 辐照效应 vue3 HTML audio 控件组件 vue3 audio音乐播放器 Audio标签自定义样式默认 vue3播放音频文件音效音乐 自定义audio播放器样式 播放暂停调整声音大小下载文件 笔记 C 环境变量 进程地址空间 ffmpeg 音视频 github 创意 社区 Flask FastAPI Waitress Gunicorn uWSGI Uvicorn react.js 前端面试题 node.js 持续部署 rust http jenkins macos transformer Dell R750XS 科技 个人开发 产品经理 agi microsoft 鸿蒙 虚拟化 半虚拟化 硬件虚拟化 Hypervisor IIS .net core Hosting Bundle .NET Framework vs2022 java-ee mysql firewalld AI编程 物联网 iot 部署 服务器配置 华为云 dell服务器 go 代理模式 硬件架构 系统架构 Reactor 设计模式 C++ websocket 微信小程序 小程序 html ansible 自动化 playbook 剧本 .netcore vscode elasticsearch 集成学习 集成测试 openEuler AI 爬虫 数据集 学习 sql KingBase stm32 W5500 OLED u8g2 TCP服务器 UOS 统信操作系统 yum oceanbase rc.local 开机自启 systemd 麒麟 c语言 嵌入式 linux驱动开发 arm开发 嵌入式硬件 文件系统 路径解析 音乐服务器 Navidrome 音流 ping++ conda kylin 深度优先 图论 并集查找 换根法 树上倍增 智能手机 NAS Termux Samba Linux ruoyi DeepSeek行业应用 DeepSeek Heroku 网站部署 postman mock mock server 模拟服务器 mock服务器 Postman内置变量 Postman随机数据 低代码 ESP32 学习方法 指令 服务器数据恢复 数据恢复 存储数据恢复 北亚数据恢复 oracle数据恢复 nuxt3 jmeter 软件测试 服务器繁忙 实时音视频 向日葵 IIS服务器 IIS性能 日志监控 react next.js 部署next.js svn 云原生 devops springboot 设置代理 实用教程 bash YOLOv8 NPU Atlas800 A300I pro 银河麒麟服务器操作系统 系统激活 sqlserver kubernetes k8s list 数据结构 safari pip Mac 系统 linux环境变量 prometheus k8s资源监控 annotations自动化 自动化监控 监控service 监控jvm 漏洞 .net 负载均衡 安全威胁分析 vscode 1.86 minicom 串口调试工具 测试工具 unix unity3d spring cloud 银河麒麟 kylin v10 麒麟 v10 网络穿透 云服务器 SSH Xterminal Docker Compose docker compose docker-compose 单片机 android studio 交互 TRAE gitlab express okhttp CORS 跨域 fpga开发 远程工作 threejs 3D HCIE 数通 大模型微调 AIGC 计算机外设 电脑 mac 软件需求 maven intellij idea 代码调试 ipdb 腾讯云 Qwen2.5-coder 离线部署 word图片自动上传 word一键转存 复制word图片 复制word图文 复制word公式 粘贴word图文 粘贴word公式 Trae AI代码编辑器 dubbo wsl2 wsl gateway Clion Nova ResharperC++引擎 Centos7 远程开发 Dify code-server echarts 信息可视化 数据分析 网页设计 1024程序员节 pillow json html5 firefox redis kamailio sip VoIP Windsurf 大数据 大数据平台 统信 国产操作系统 虚拟机安装 微信 微信分享 Image wxopensdk jar spring 串口服务器 ci/cd 微信小程序域名配置 微信小程序服务器域名 微信小程序合法域名 小程序配置业务域名 微信小程序需要域名吗 微信小程序添加域名 qt excel WSL2 经验分享 程序人生 WebRTC gpt webrtc YOLOv12 chatgpt oneapi 开源 mongodb pdf 多线程服务器 Linux网络编程 HarmonyOS Next springsecurity6 oauth2 授权服务器 token sas DeepSeek-R1 API接口 3d 数学建模 命名管道 客户端与服务端通信 rabbitmq av1 电视盒子 机顶盒ROM 魔百盒刷机 visualstudio IDE AI 原生集成开发环境 Trae AI 安装教程 GPU环境配置 Ubuntu22 CUDA PyTorch Anaconda安装 EasyConnect Cline gitee ecmascript nextjs reactjs https 流式接口 ArcTS 登录 ArcUI GridItem DigitalOcean GPU服务器购买 GPU服务器哪里有 GPU服务器 apache Kylin-Server 服务器安装 openwrt Deepseek hadoop mount挂载磁盘 wrong fs type LVM挂载磁盘 Centos7.9 搜索引擎 Agent LLM RAID RAID技术 磁盘 存储 源码剖析 rtsp实现步骤 流媒体开发 gpu算力 postgresql c# NPS 雨云服务器 雨云 环境迁移 pygame 小游戏 五子棋 温湿度数据上传到服务器 Arduino HTTP es jvm cpu 内存 实时 使用 软件工程 相差8小时 UTC 时间 Java ollama下载加速 大模型 混合开发 环境安装 JDK 媒体 微信公众平台 僵尸进程 C语言 企业微信 Linux24.04 deepin VMware安装Ubuntu Ubuntu安装k8s 状态管理的 UDP 服务器 Arduino RTOS mysql离线安装 ubuntu22.04 mysql8.0 kvm 无桌面 命令行 matlab centos-root /dev/mapper yum clean all df -h / du -sh web Socket asi_bench 博客 宕机切换 服务器宕机 压力测试 springboot远程调试 java项目远程debug docker远程debug java项目远程调试 springboot远程 ecm bpm 蓝耘科技 元生代平台工作流 ComfyUI mybatis 缓存 ddos stm32项目 llama3 Chatglm 开源大模型 多进程 系统开发 binder 车载系统 framework 源码环境 debian iDRAC R720xd CPU 主板 电源 网卡 PVE zotero WebDAV 同步失败 远程桌面 服务器无法访问 ip地址无法访问 无法访问宝塔面板 宝塔面板打不开 云服务 selenium XFS xfs文件系统损坏 I_O error Linux PID 测试用例 功能测试 shell 磁盘监控 kind minio LInux 前后端分离 jupyter git 华为认证 网络工程师 KVM pgpool visual studio code 编辑器 arm 田俊楠 FunASR ASR 系统安全 file server http server web server wireshark NFS muduo X11 Xming gcc g++ g++13 生物信息学 Cookie uni-file-picker 拍摄从相册选择 uni.uploadFile H5上传图片 微信小程序上传图片 目标跟踪 OpenVINO 推理应用 make命令 makefile文件 游戏程序 王者荣耀 Wi-Fi c DNS 开机自启动 Spring Security ios iphone tcpdump Portainer搭建 Portainer使用 Portainer使用详解 Portainer详解 Portainer portainer iftop 网络流量监控 outlook ue4 着色器 ue5 虚幻 远程连接 rdp 实验 机器人 安卓 云电竞 云电脑 todesk 蓝桥杯 交换机 硬件 设备 GPU PCI-Express QQ bot Docker cuda cudnn anaconda mamba Vmamba 阻塞队列 生产者消费者模型 服务器崩坏原因 jetty undertow Linux无人智慧超市 LInux多线程服务器 QT项目 LInux项目 单片机项目 鸿蒙系统 ISO镜像作为本地源 cnn GoogLeNet 超融合 DeepSeek r1 Open WebUI Erlang OTP gen_server 热代码交换 事务语义 MNN Qwen 信息与通信 ip ui 备份SQL Server数据库 数据库备份 傲梅企业备份网络版 匿名管道 宝塔 华为od OD机试真题 华为OD机试真题 服务器能耗统计 gaussdb DevEco Studio 银河麒麟桌面操作系统 Kylin OS 国产化 xss 进程信号 在线预览 xlsx xls文件 在浏览器直接打开解析xls表格 前端实现vue3打开excel 文件地址url或接口文档流二进 CLion MacOS录屏软件 Redis Desktop 图像处理 游戏机 鲲鹏 昇腾 npu pppoe radius eclipse hugo Netty 即时通信 NIO 游戏引擎 SWAT 配置文件 服务管理 网络共享 curl wget saltstack vasp安装 AI写作 AI作画 聊天室 docker run 数据卷挂载 交互模式 RAGFLOW RAG 检索增强生成 文档解析 大模型垂直应用 ocr 大语言模型 命令 micropython esp32 mqtt AI agent 思科模拟器 思科 Cisco r语言 数据挖掘 数据可视化 CDN 医疗APP开发 app开发 dba 算力 Radius 技能大赛 googlecloud npm 模拟器 教程 qt项目 qt项目实战 qt教程 XCC Lenovo 国标28181 视频监控 监控接入 语音广播 流程 SIP SDP Linux的基础指令 其他 linux 命令 sed 命令 繁忙 解决办法 替代网站 汇总推荐 AI推理 安全架构 权限 windwos防火墙 defender防火墙 win防火墙白名单 防火墙白名单效果 防火墙只允许指定应用上网 防火墙允许指定上网其它禁止 根服务器 clickhouse embedding 社交电子 数据库系统 高效远程协作 TrustViewer体验 跨设备操作便利 智能远程控制 eNSP 网络规划 VLAN 企业网络 prompt easyui AI大模型 langchain EMQX MQTT 通信协议 kafka hibernate skynet 弹性计算 计算虚拟化 弹性裸金属 virtualenv dify ragflow 历史版本 下载 安装 飞牛nas fnos nvidia linux安装配置 chfs ubuntu 16.04 阿里云ECS 小番茄C盘清理 便捷易用C盘清理工具 小番茄C盘清理的优势尽显何处? 教你深度体验小番茄C盘清理 C盘变红?!不知所措? C盘瘦身后电脑会发生什么变化? kali 共享文件夹 虚拟机 LORA NLP 显示管理器 lightdm gdm yum源切换 更换国内yum源 宝塔面板 同步 备份 建站 laravel EMUI 回退 降级 升级 grafana 直流充电桩 充电桩 IPMI junit ESXi 职场和发展 需求分析 规格说明书 bug 豆瓣 追剧助手 迅雷 nas 裸金属服务器 弹性裸金属服务器 ip命令 新增网卡 新增IP 启动网卡 p2p zabbix 火绒安全 Nuxt.js HTTP 服务器控制 ESP32 DeepSeek nac 802.1 portal aws 支付 微信支付 开放平台 灵办AI Google pay Apple pay 备选 网站 api 调用 示例 链表 服务器主板 AI芯片 AD域 vSphere vCenter 软件定义数据中心 sddc 反向代理 致远OA OA服务器 服务器磁盘扩容 docker命令大全 5G 3GPP 卫星通信 Playwright 自动化测试 单元测试 dns 程序员 大模型入门 JAVA eureka 消息队列 边缘计算 智能硬件 查询数据库服务IP地址 SQL Server 图形化界面 AutoDL 怎么卸载MySQL MySQL怎么卸载干净 MySQL卸载重新安装教程 MySQL5.7卸载 Linux卸载MySQL8.0 如何卸载MySQL教程 MySQL卸载与安装 rpc GCC crosstool-ng ceph 监控k8s 监控kubernetes 视觉检测 计算机 Linux环境 VMware创建虚拟机 sqlite MS Materials openssl 密码学 版本 业界资讯 tidb GLIBC 模拟退火算法 Ubuntu 24 常用命令 Ubuntu 24 Ubuntu vi 异常处理 Docker Hub docker pull 镜像源 daemon.json mosquitto 银河麒麟高级服务器 外接硬盘 Kylin 深度求索 私域 知识库 selete 高级IO flink Claude 多层架构 解耦 华为机试 Python 大模型面经 大模型学习 rocketmq AISphereButler 课程设计 自定义客户端 SAS WebUI DeepSeek V3 ukui 麒麟kylinos openeuler rust腐蚀 DenseNet wordpress 无法访问wordpess后台 打开网站页面错乱 linux宝塔面板 wordpress更换服务器 框架搭建 qemu libvirt 回显服务器 UDP的API使用 frp armbian u-boot 大模型教程 腾讯云大模型知识引擎 efficientVIT YOLOv8替换主干网络 TOLOv8 remote-ssh 分析解读 gradle C# MQTTS 双向认证 emqx RustDesk自建服务器 rustdesk服务器 docker rustdesk mcu ftp VPS pyqt can 线程池 VM搭建win2012 win2012应急响应靶机搭建 攻击者获取服务器权限 上传wakaung病毒 应急响应并溯源 挖矿病毒处置 应急响应综合性靶场 报错 小艺 Pura X 恒源云 tcp ux 多线程 vscode1.86 1.86版本 ssh远程连接 open Euler dde 统信UOS USB网络共享 RTMP 应用层 LLM Web APP Streamlit camera Arduino 电子信息 监控k8s集群 集群内prometheus big data MacMini 迷你主机 mini Apple opensearch helm IDEA 无人机 宠物 毕业设计 免费学习 宠物领养 宠物平台 飞书 孤岛惊魂4 uniapp vue 游戏服务器 TrinityCore 魔兽世界 ssh漏洞 ssh9.9p2 CVE-2025-23419 lua sysctl.conf vm.nr_hugepages adobe 传统数据库升级 银行 LLMs k8s集群资源管理 云原生开发 单一职责原则 网络编程 聊天服务器 套接字 TCP 客户端 vmware 卡死 IPMITOOL BMC 硬件管理 opcua opcda KEPServer安装 数据库架构 数据管理 数据治理 数据编织 数据虚拟化 自动化编程 open webui idm spark HistoryServer Spark YARN jobhistory IO模型 VR手套 数据手套 动捕手套 动捕数据手套 Headless Linux 音乐库 群晖 飞牛 ai小智 语音助手 ai小智配网 ai小智教程 esp32语音助手 diy语音助手 asp.net大文件上传 asp.net大文件上传下载 asp.net大文件上传源码 ASP.NET断点续传 asp.net上传文件夹 asp.net上传大文件 .net core断点续传 文件分享 中间件 iis VSCode 移动云 可信计算技术 Linux awk awk函数 awk结构 awk内置变量 awk参数 awk脚本 awk详解 ros2 moveit 机器人运动 FTP 服务器 网络结构图 zookeeper nfs n8n 工作流 workflow 服务器部署ai模型 SSL 域名 rsyslog Anolis nginx安装 linux插件下载 7z ruby 显示过滤器 ICMP Wireshark安装 输入法 raid5数据恢复 磁盘阵列数据恢复 僵尸世界大战 游戏服务器搭建 银河麒麟操作系统 telnet 远程登录 驱动开发 硬件工程 嵌入式实习 perf hive DBeaver 数据仓库 kerberos 网络用户购物行为分析可视化平台 大数据毕业设计 v10 软件 远程 执行 sshpass 操作 服务网格 istio 多个客户端访问 IO多路复用 TCP相关API 单例模式 chrome devtools chromedriver openstack VMware Xen 黑客技术 mariadb URL 本地部署 架构与原理 技术共享 arkUI SysBench 基准测试 SSE elk Logstash 日志采集 大文件分片上传断点续传及进度条 如何批量上传超大文件并显示进度 axios大文件切片上传详细教 node服务器合并切片 vue3大文件上传报错提示错误 大文件秒传跨域报错cors 交叉编译 Cursor 网工 压测 ECS ssrf 失效的访问控制 MI300x string模拟实现 深拷贝 浅拷贝 经典的string类问题 三个swap Unity Dedicated Server Host Client 无头主机 开发环境 SSL证书 网络攻击模型 语法 vue-i18n 国际化多语言 vue2中英文切换详细教程 如何动态加载i18n语言包 把语言json放到服务器调用 前端调用api获取语言配置文件 xrdp 视频编解码 sdkman Ubuntu 24.04.1 轻量级服务器 redhat protobuf 序列化和反序列化 性能测试 odoo 服务器动作 Server action 政务 分布式系统 监控运维 Prometheus Grafana 能力提升 面试宝典 技术 IT信息化 Dell HPE 联想 浪潮 崖山数据库 YashanDB 策略模式 黑苹果 实时互动 直播推流 gpt-3 文心一言 高效日志打印 串口通信日志 服务器日志 系统状态监控日志 异常记录日志 自动驾驶 毕设 midjourney alias unalias 别名 大模型应用 强制清理 强制删除 mac废纸篓 netty 代码托管服务 .net mvc断点续传 远程控制 远程看看 远程协助 远程过程调用 Windows环境 gitea risc-v regedit 开机启动 佛山戴尔服务器维修 佛山三水服务器维修 ipython etcd 数据安全 RBAC xml 矩阵 Ubuntu DeepSeek DeepSeek Ubuntu DeepSeek 本地部署 DeepSeek 知识库 DeepSeek 私有化知识库 本地部署 DeepSeek DeepSeek 私有化部署 seatunnel 三级等保 服务器审计日志备份 金融 FTP服务器 服务器管理 配置教程 网站管理 源码 Ark-TS语言 虚拟显示器 干货分享 黑客工具 密码爆破 bootstrap cmos 京东云 软考 VS Code 基础入门 编程 css Hive环境搭建 hive3环境 Hive远程模式 工业4.0 联想开天P90Z装win10 Invalid Host allowedHosts SSH 服务 SSH Server OpenSSH Server 软件构建 AD 域管理 网站搭建 serv00 VMware安装mocOS macOS系统安装 微信开放平台 微信公众号配置 bonding 链路聚合 双系统 GRUB引导 Linux技巧 执法记录仪 智能安全帽 smarteye tailscale derp derper 中转 flash-attention 线性代数 电商平台 互信 小智AI服务端 xiaozhi TTS C++软件实战问题排查经验分享 0xfeeefeee 0xcdcdcdcd 动态库加载失败 程序启动失败 程序运行权限 标准用户权限与管理员权限 重启 排查 系统重启 日志 原因 Minecraft DOIT 四博智联 epoll cursor MCP server C/S windows日志 USB转串口 CH340 飞牛NAS 飞牛OS MacBook Pro 我的世界服务器搭建 minecraft thingsboard H3C Ubuntu Server Ubuntu 22.04.5 freebsd 移动魔百盒 自学笔记 小米 澎湃OS Android 上传视频至服务器代码 vue3批量上传多个视频并预览 如何实现将本地视频上传到网页 element plu视频上传 ant design vue vue3本地上传视频及预览移除 端口 查看 ss deployment daemonset statefulset cronjob ubuntu20.04 ros ros1 Noetic 20.04 apt 安装 读写锁 本地部署AI大模型 办公自动化 自动化生成 pdf教程 AI Agent 字节智能运维 rnn Unity插件 iventoy VmWare OpenEuler top Linux top top命令详解 top命令重点 top常用参数 arcgis 端口测试 云桌面 微软 AD域控 证书服务器 个人博客 deepseek r1 react native deep learning cd 目录切换 影刀 #影刀RPA# 实习 粘包问题 ABAP rag ragflow 源码启动 运维监控 rtsp服务器 rtsp server android rtsp服务 安卓rtsp服务器 移动端rtsp服务 大牛直播SDK word pyautogui Jellyfin 镜像 存储维护 NetApp存储 EMC存储 带外管理 figma TrueLicense Linux find grep grub 版本升级 扩容 钉钉 uv 代理 游戏开发 onlyoffice HarmonyOS 磁盘镜像 服务器镜像 服务器实时复制 实时文件备份 navicat 大模型推理 OpenManus ROS 抓包工具 rustdesk 金仓数据库 2025 征文 数据库平替用金仓 x64 SIGSEGV xmm0 less dns是什么 如何设置电脑dns dns应该如何设置 apt 国内源 MQTT协议 消息服务器 代码 miniapp 真机调试 调试 debug 断点 网络API请求调试方法 Attention 信号处理 docker desktop image tensorflow bat 串口驱动 CH341 uart 485 分布式训练 rclone AList webdav fnOS xpath定位元素 智能音箱 智能家居 SVN Server tortoise svn RAGFlow 本地知识库部署 DeepSeek R1 模型 软件卸载 系统清理 bcompare Beyond Compare docker部署翻译组件 docker部署deepl docker搭建deepl java对接deepl 翻译组件使用 强化学习 matplotlib 程序 RoboVLM 通用机器人策略 VLA设计哲学 vlm fot robot 视觉语言动作模型 具身智能 相机 物联网开发 etl 环境配置 自动化任务管理 HAProxy Kali IM即时通讯 剪切板对通 HTML FORMAT edge浏览器 SEO log4j 嵌入式Linux IPC 中兴光猫 换光猫 网络桥接 自己换光猫 Xinference vr ArkUI 多端开发 智慧分发 应用生态 鸿蒙OS c/c++ 串口 vpn 内网服务器 内网代理 内网通信 mq ubuntu24 vivado24 ArkTs PX4 健康医疗 互联网医院 MacOS 免费域名 域名解析 fd 文件描述符 kotlin DocFlow 用户缓冲区 模拟实现 perl cocoapods xcode 元服务 应用上架 李心怡 语音识别 换源 Debian SenseVoice Linux的权限 Mac内存不够用怎么办 渗透 wpf Python基础 Python教程 Python技巧 db WLAN yaml Ultralytics 可视化 trae EtherNet/IP串口网关 EIP转RS485 EIP转Modbus EtherNet/IP网关协议 EIP转RS485网关 EIP串口服务器 yolov8 wsgiref Web 服务器网关接口 AnythingLLM AnythingLLM安装 信创 信创终端 中科方德 deekseek 软链接 硬链接 sqlite3 idea su sudo jina CrewAI rime Ubuntu22.04 开发人员主页 基础环境 WebVM 做raid 装系统 trea Java Applet URL操作 服务器建立 Socket编程 网络文件读取 流水线 脚本式流水线 ardunio BLE webstorm composer wps 信号 并查集 leetcode 项目部署到linux服务器 项目部署过程 CVE-2024-7347 web3 问题解决 键盘 网络药理学 生信 gromacs 分子动力学模拟 MD 动力学模拟 开发 autodl ssh远程登录 KylinV10 麒麟操作系统 Vmware linux上传下载 浏览器开发 AI浏览器 iBMC UltraISO aarch64 编译安装 HPC 代理服务器 EtherCAT转Modbus ECT转Modbus协议 EtherCAT转485网关 ECT转Modbus串口网关 EtherCAT转485协议 ECT转Modbus网关 IMM 烟花代码 烟花 元旦 性能调优 安全代理 python3.11 lsb_release /etc/issue /proc/version uname -r 查看ubuntu版本 树莓派 VNC ubuntu24.04.1 程序员创富 域名服务 DHCP 符号链接 配置 磁盘清理 powerpoint 远程服务 dity make fast xshell termius iterm2 GIS 遥感 WebGIS Typore 实战案例 searxng neo4j 数据库开发 database Docker引擎已经停止 Docker无法使用 WSL进度一直是0 镜像加速地址 人工智能生成内容 大大通 第三代半导体 碳化硅 Windows ai工具 java-rocketmq ldap keepalived sonoma 自动更新 AP配网 AK配网 小程序AP配网和AK配网教程 WIFI设备配网小程序UDP开 产测工具框架 IMX6ULL 管理框架 ShenTong 内网环境 h.264 知识图谱 firewall 查看显卡进程 fuser TCP协议 cfssl 拓扑图 抗锯齿 IMX317 MIPI H265 VCU milvus 合成模型 扩散模型 图像生成 QT 5.12.12 QT开发环境 Ubuntu18.04 序列化反序列化 网卡的名称修改 eth0 ens33 nvm whistle 线程 cpp-httplib P2P HDLC SRS 流媒体 直播 防火墙 NAT转发 NAT Server MVS 海康威视相机 Deepseek-R1 私有化部署 推理模型 聚类 性能分析 CentOS OpenHarmony win服务器架设 windows server sequoiaDB 虚拟局域网 dash 正则表达式 迁移指南 捆绑 链接 谷歌浏览器 youtube google gmail llama.cpp 图形渲染 常用命令 文本命令 目录命令 proxy模式 sentinel prometheus数据采集 prometheus数据模型 prometheus特点 显卡驱动 css3 OpenSSH 容器技术 IPv4 子网掩码 公网IP 私有IP SSH 密钥生成 SSH 公钥 私钥 生成 主从复制 状态模式 swoole 企业网络规划 华为eNSP 考研 在线office docker搭建pg docker搭建pgsql pg授权 postgresql使用 postgresql搭建 iperf3 带宽测试 我的世界 我的世界联机 数码 UOS1070e Ubuntu共享文件夹 共享目录 Linux共享文件夹 UDP seleium webgl 加解密 Yakit yaklang 对比 工具 meld DiffMerge docker搭建nacos详解 docker部署nacos docker安装nacos 腾讯云搭建nacos centos7搭建nacos hexo triton 模型分析 服务器时间 流量运营 chrome 浏览器下载 chrome 下载安装 谷歌浏览器下载 私有化 lio-sam SLAM glibc MySql AI-native Docker Desktop HiCar CarLife+ CarPlay QT RK3588 软负载 harmonyOS面试题 安防软件 邮件APP 免费软件 Node-Red 编程工具 流编程 毕昇JDK fstab 搜狗输入法 中文输入法 rpa CentOS Stream 端口聚合 windows11 System V共享内存 进程通信 yolov5 网络建设与运维 西门子PLC 通讯 接口优化 k8s二次开发 云耀服务器 nlp gnu 多路转接 解决方案 数字证书 签署证书 vllm docker部署Python 智能电视 yum换源 kernel 搭建个人相关服务器 网络爬虫 开机黑屏 增强现实 沉浸式体验 应用场景 技术实现 案例分析 AR 风扇控制软件 沙盒 服务器正确解析请求体 AI员工 虚幻引擎 嵌入式系统开发 Sealos 论文阅读 欧标 OCPP 极限编程 热榜 IO 网络搭建 神州数码 神州数码云平台 云平台 conda配置 conda镜像源 稳定性 看门狗 PPI String Cytoscape CytoHubba nosql 大模型部署 js Qwen2.5-VL ArtTS MobaXterm 鸿蒙开发 移动开发 项目部署 推荐算法 dock 加速 macOS mm-wiki搭建 linux搭建mm-wiki mm-wiki搭建与使用 mm-wiki使用 mm-wiki详解 hosts MDK 嵌入式开发工具 论文笔记 sublime text 离线部署dify 本地化部署 ranger MySQL8.0 玩机技巧 软件分享 软件图标 达梦 DM8 HarmonyOS NEXT 原生鸿蒙 visual studio