解码Linux文件IO之中文字库原理与应用

news/2025/10/26 15:02:23/文章来源:https://www.cnblogs.com/YouEmbedded/p/19165825

中文字库核心概念

在嵌入式项目中显示汉字,需解决 “计算机如何存储和识别汉字” 的问题 —— 早期 ANSI 字符集仅收录 256 个字符(无中文),因此中国制定了GB2312 简体中文字符集,成为嵌入式中文显示的核心标准。

从 ANSI 到 GB2312 的演进

  • ANSI 字符集局限:仅包含英文、数字和少量符号(共 256 个),无法满足中文存储需求。
  • GB2312 字符集(GB2312-80)
    • 全称《信息交换用汉字编码字符集・基本集》,1981 年实施,覆盖 99.75% 的常用汉字,满足主流场景。
    • 收录内容:共 7445 个图形字符,包括:
      • 6763 个汉字(一级汉字 3755 个,按拼音排序;二级汉字 3008 个,按部首 / 笔画排序);
      • 682 个全角字符(拉丁字母、希腊字母、日文假名、俄文字母等)。

GB2312 的分区规则(关键!定位汉字的基础)

GB2312 将所有字符按 “区 - 位” 划分,每个区含 94 个字符(位),共 94 个区,分区规则决定了汉字的存储位置:

区号范围 字符类型 说明
01-09 特殊符号 标点、序号、数字、拼音符号等
10-15 未编码(空区) 预留区域
16-55 一级汉字(常用字) 按拼音字母顺序排列(如 “啊” 在 16 区 01 位)
56-87 二级汉字(生僻字) 按部首和笔画数排序
88-94 未编码(空区) 预留区域

注意:只有 “区 + 位” 的组合(即区位码),才能唯一确定一个字符,与汉字的显示大小无关。

汉字编码与字库定位

GB2312 通过双字节编码存储汉字,且通过 “区码 + 位码” 定位汉字在字库中的位置,这是中文显示的核心逻辑。

双字节编码规则(区码与位码)

GB2312 汉字用 2 个字节表示(高字节 = 区码,低字节 = 位码),编码计算规则如下:

  • 区号:对应字符所在的 “区”(1-94),转换为区码(高字节):区码 = 0xA0 + 区号
  • 位号:对应字符在区内的 “位”(1-94),转换为位码(低字节):位码 = 0xA0 + 位号
    • 原因:0x00~0xFF为ASCII码,避免和 ASCII 码冲突
    • 0x00~0x1F:不可见控制字符(如换行、回车);
    • 0x20~0x7E:可见字符(如字母A0x41、数字00x30);
    • 0x80~0xFF:ASCII 码未定义的 “扩展区域”(早期未被标准化使用)。
  • 最终汉字编码 = 区码(高字节) + 位码(低字节)(十六进制)。

示例:“啊” 字的编码计算

  • “啊” 是一级汉字,位于 16 区 01 位(区号 16,位号 01);
  • 区码 = 0xA0 + 16 = 0xB0(十六进制);
  • 位码 = 0xA0 + 1 = 0xA1(十六进制);
  • 因此 “啊” 的 GB2312 编码为 0xB0A1(双字节:高字节 0xB0,低字节 0xA1)。

编码验证代码

GB2312 汉字是双字节,需 2 个字节存储,数组大小应为 2,以下验证代码(需确保文件编码为 GB2312):

#include <stdio.h>
int main(int argc, char const *argv[]) {// GB2312汉字为双字节,数组大小设为2(无需额外存'\0',因不是字符串)char font_buf[2] = "啊";  // 正确:2字节存储双字节编码// 输出高字节(区码)和低字节(位码)printf("高字节(区码):%#x\n", (unsigned char)font_buf[0]);  // 输出0xB0(正确)printf("低字节(位码):%#x\n", (unsigned char)font_buf[1]);  // 输出0xA1(正确)return 0;
}

编译运行注意

  • 若编译器默认编码为 UTF-8,需手动设置文件编码为 GB2312(如 VS Code 右下角切换);
  • 运行结果应为0xb00xa1,与 “啊” 的编码一致,若输出其他值,需检查文件编码。

汉字在字库中的位置定位

汉字在字库中的存储位置由区号和位号决定(与汉字大小无关),位置计算分两步:

确定汉字在字库中的索引:每个区有 94 个汉字,因此索引 =(区号 - 1)× 94 +(位号 - 1);

  • 示例:“啊”(区号 16,位号 1)的索引 =(16-1)×94 +(1-1)= 15×94 = 1410(第 1411 个汉字,从 0 开始)。

计算字库中的偏移量:偏移量 = 索引 × 单个汉字占用字节数;

  • 单个汉字占用字节数由显示分辨率决定(点阵字库),公式:字节数 = (宽度 / 8) × 高度(1 字节 = 8 像素)。

点阵汉字占用字节计算(关键公式)

嵌入式常用点阵字库(如 16×16、24×24),每个汉字的占用字节数由分辨率决定,示例如下:

汉字分辨率 宽度(像素) 高度(像素) 每行列数(字节)= 宽度 / 8 总字节数 = 每行列数 × 高度
16×16 16 16 16/8 = 2 2×16 = 32
24×24 24 24 24/8 = 3 3×24 = 72
32×32 32 32 32/8 = 4 4×32 = 128

示例:16×16 的 “你” 字,共占用 32 字节,点阵数据如下(每行 2 字节,16 行):

image

显示逻辑:将点阵数据的每一位(0/1)与 LCD 像素对应,1 表示显示前景色,0 表示背景色,逐行逐像素绘制。

字库类型与生成

嵌入式中文显示常用两种字库:点阵字库(固定分辨率)和TrueType 字库(矢量可缩放),需根据需求选择。

点阵字库(固定分辨率)

  • 特点:基于像素点阵存储,每个汉字对应固定的像素数据,如 16×16、24×24;
    • 优点:结构简单,解码快,占用内存小,适合资源有限的嵌入式设备(如 51 单片机、小型 ARM 开发板);
    • 缺点:分辨率固定,放大后会出现锯齿(失真),不同分辨率需不同字库(如 16×16 和 24×24 需两个字库)。
  • 生成工具:PC 端取模软件(如 PCtoLCD2002、字模大师),可自定义分辨率、取模方式(行列式、行优先)、颜色(16 色 / 256 色)。
  • 使用场景:OLED 屏(小分辨率)、简单 LCD 显示(固定字体大小)。

TrueType 字库(矢量可缩放)

  • 特点:基于数学矢量曲线描述字体轮廓,而非像素,文件格式为.ttf(TrueType Font);

    • 优点:可任意缩放不失真,支持多种字体风格(宋体、黑体、楷体),一个字库支持所有分辨率;
    • 缺点:解码需计算矢量曲线,占用 CPU 资源稍多,适合中高端嵌入式设备(如 ARM Cortex-A 系列开发板)。
  • 系统存放路径

    • Windows:C:\Windows\Fonts(如simkai.ttf是楷体,simsun.ttf是宋体);

      image

    • Linux:/usr/share/fonts(系统默认路径,用户可添加自定义路径)。

  • 开发板移植:将 Windows 的.ttf文件(如simkai.ttf)通过scp拷贝到开发板的/usr/share/fonts目录,即可被程序加载使用:

    # 示例:将Windows的simkai.ttf拷贝到开发板(开发板IP:192.168.1.100)
    scp C:\Windows\Fonts\simkai.ttf root@192.168.1.100:/usr/share/fonts/
    

嵌入式中文字库调用(基于 TTF 字库)

嵌入式中调用 TTF 字库需依赖字体库接口(如简化版font接口或开源FreeType库)

font.h(头文件) libfont.a(字体库)

图解

image

核心函数详解(含参数 / 返回值注释)

假设使用嵌入式简化字体库(如基于FreeType封装),核心函数包括 “加载字库→设置字体大小→创建画布→绘制文字→显示到 LCD”,函数注释如下:

加载 TTF 字库文件

/*** @brief 加载TrueType字库文件(如simkai.ttf楷体)* @param fontPath TTF字库文件路径(例如"/usr/share/fonts/simkai.ttf")* @return 成功:指向font结构体的指针(后续字体操作依赖此指针);失败:NULL* @note 失败原因可能包括:路径错误、文件不存在、权限不足(建议chmod 644 simkai.ttf)*/
font* fontLoad(char* fontPath);

设置字体显示大小

/*** @brief 设置字体的显示高度(像素)* @param f 已加载的font指针(fontLoad返回值,不可为NULL)* @param pixels 字体高度(像素,如16、24、72,宽度按字体比例自动计算)* @note 无返回值,若f为NULL或pixels≤0,可能导致后续绘制异常* @example 显示大尺寸楷体:fontSetSize(f, 72); // 72像素高*/
void fontSetSize(font* f, s32 pixels);

创建带初始化的画布

/*** @brief 创建画布(存储文字像素数据)并初始化为指定背景色* @param width 画布宽度(像素,需≥文字总宽度,避免截断)* @param height 画布高度(像素,需≥字体高度,避免截断)* @param byteperpixel 位深(字节/像素,LCD通常为4字节ARGB)* @param c 背景色(ARGB格式,通过getColor(a,b,c,d)生成,如getColor(255,255,255,255)为白色)* @return 成功:指向bitmap结构体的指针;失败:NULL(内存分配失败)* @note 显示“晚安”(2个汉字)用72号楷体时,画布宽建议≥200(72×2 + 预留间距)*/
bitmap* createBitmapWithInit(u32 width, u32 height, u32 byteperpixel, color c);

将文字绘制到画布

/*** @brief 将字符串(支持中文楷体)绘制到画布指定位置* @param f 已加载的font指针(不可为NULL)* @param screen 目标画布指针(createBitmapWithInit返回值,不可为NULL)* @param x 文字在画布上的起始x坐标(左上角为(0,0))* @param y 文字在画布上的起始y坐标(建议设为字体高度,避免顶部截断)* @param text 待绘制字符串(GB2312编码,如"楷体测试")* @param c 文字颜色(ARGB格式,如getColor(255,255,0,0)为红色)* @param maxWidth 文字显示的最大宽度(像素,超过此宽度会截断)* @note 字符串需为GB2312编码,否则楷体显示乱码;maxWidth用于限制单行显示范围*/
void fontPrint(font* f, bitmap* screen, s32 x, s32 y, char* text, color c, s32 maxWidth);

将画布显示到 LCD

/*** @brief 将画布像素数据显示到LCD指定位置* @param p LCD内存映射首地址(mmap返回的unsigned int*指针)* @param px 画布在LCD上的起始x坐标(左上角为(0,0))* @param py 画布在LCD上的起始y坐标* @param bm 待显示的画布指针(不可为NULL)* @note 需确保px + bm->width ≤ LCD宽度,py + bm->height ≤ LCD高度,避免越界*/
void show_font_to_lcd(unsigned int* p, int px, int py, bitmap* bm);

基础调用示例(用楷体显示 “晚安” 到 LCD)

结合 LCD 初始化,使用simkai.ttf楷体显示文字的完整代码:

#include "font.h"
#include <unistd.h>  // 包含sleep函数声明// 初始化LCD设备,增加错误信息输出
struct LcdDevice *init_lcd(const char *device) {if (device == NULL) {fprintf(stderr, "Error: device path is NULL\n");return NULL;}// 申请LCD设备结构体空间struct LcdDevice *lcd = malloc(sizeof(struct LcdDevice));if (lcd == NULL) {perror("malloc LcdDevice failed");return NULL;}// 打开LCD设备文件lcd->fd = open(device, O_RDWR);if (lcd->fd < 0) {perror("open lcd device failed");free(lcd);return NULL;}// 内存映射LCD显存(800×480分辨率,4字节ARGB)lcd->mp = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->fd, 0);if (lcd->mp == MAP_FAILED) {perror("mmap lcd failed");close(lcd->fd);free(lcd);return NULL;}return lcd;
}// 释放LCD设备资源
void release_lcd(struct LcdDevice *lcd) {if (lcd == NULL) return;// 解除内存映射if (lcd->mp != MAP_FAILED && lcd->mp != NULL) {munmap(lcd->mp, 800 * 480 * 4);lcd->mp = NULL;}// 关闭文件描述符if (lcd->fd >= 0) {close(lcd->fd);lcd->fd = -1;}// 释放结构体空间free(lcd);
}int main() {struct LcdDevice *lcd = NULL;font *f = NULL;bitmap *bm = NULL;// 初始化LCDlcd = init_lcd("/dev/fb0");if (lcd == NULL) {fprintf(stderr, "初始化LCD失败\n");goto exit;  // 统一跳转到资源释放处}// 加载字体(确保字库文件存在且路径正确)f = fontLoad("/usr/share/fonts/simkai.ttf");if (f == NULL) {fprintf(stderr, "加载字体文件失败\n");goto exit;}// 设置字体大小(72像素高度)fontSetSize(f, 72);// 创建画布(200×200,4字节ARGB,透明背景)// 注意:getColor参数为ARGB,此处a=0表示完全透明bm = createBitmapWithInit(200, 200, 4, getColor(0, 255, 255, 255));if (bm == NULL) {fprintf(stderr, "创建画布失败\n");goto exit;}// 绘制中文字符(确保源文件编码为GB2312,与字库匹配)char text[] = "晚安";// 参数说明:x=0,y=72(基线位置),红色文字(ARGB:0,255,0,0),maxWidth=0表示不限制宽度fontPrint(f, bm, 0, 72, text, getColor(0, 255, 0, 0), 0);// 显示画布到LCD的(0,0)和(200,200)位置(确保不超出屏幕范围:800×480)show_font_to_lcd(lcd->mp, 0, 0, bm);show_font_to_lcd(lcd->mp, 200, 200, bm);// 停留5秒观察效果sleep(5);exit:  // 统一释放所有资源destroyBitmap(bm);    // 释放画布fontUnload(f);        // 卸载字体release_lcd(lcd);     // 释放LCD资源return 0;
}
#程序中使用了 floor、ceil 等数学函数,链接阶段需要关联数学库(libm)
arm-linux-gcc main.c -o main -L./ -lfont -lm 

实战:用楷体实时显示系统时间(1 秒刷新)

需求:格式化时间为 “2024 年 5 月 15 日 15:00:04”,用楷体显示在 LCD 中央,每秒刷新(避免重叠)。

#include "font.h"
#include <time.h>
#include <unistd.h>
#include <string.h>// LCD分辨率配置(根据实际设备修改)
#define LCD_WIDTH 800
#define LCD_HEIGHT 480
#define LCD_SIZE (LCD_WIDTH * LCD_HEIGHT * 4)  // 每个像素4字节(ARGB)// 时间显示参数配置
#define FONT_SIZE 48          // 字体大小
#define TIME_X 100            // 时间显示起始X坐标
#define TIME_Y 180            // 时间显示起始Y坐标
#define AREA_WIDTH 600        // 显示区域宽度
#define AREA_HEIGHT 120       // 显示区域高度// 初始化LCD设备
struct LcdDevice* lcdInit() {struct LcdDevice* lcd = malloc(sizeof(struct LcdDevice));if (!lcd) {perror("malloc lcd device failed");return NULL;}// 打开LCD设备lcd->fd = open("/dev/fb0", O_RDWR);if (lcd->fd == -1) {perror("open /dev/fb0 failed");free(lcd);return NULL;}// 内存映射LCD设备lcd->mp = mmap(NULL, LCD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->fd, 0);if (lcd->mp == MAP_FAILED) {perror("mmap lcd failed");close(lcd->fd);free(lcd);return NULL;}return lcd;
}// 关闭LCD设备
void lcdClose(struct LcdDevice* lcd) {if (lcd) {munmap(lcd->mp, LCD_SIZE);close(lcd->fd);free(lcd);}
}int main() {// 初始化LCDstruct LcdDevice* lcd = lcdInit();if (!lcd) {return -1;}// 加载字体(请确保字体文件路径正确)font* f = fontLoad("/usr/share/fonts/simkai.ttf");  // 中文字体if (!f) {fprintf(stderr, "加载字体失败,请检查字体路径\n");lcdClose(lcd);return -1;}// 设置字体大小fontSetSize(f, FONT_SIZE);// 创建显示画布(黑色背景)bitmap* timeBmp = createBitmapWithInit(AREA_WIDTH, AREA_HEIGHT, 4,  // 4字节/像素(ARGB)getColor(255, 0, 0, 0)  // 黑色背景);if (!timeBmp) {fprintf(stderr, "创建画布失败\n");fontUnload(f);lcdClose(lcd);return -1;}// 循环显示时间while (1) {// 获取当前时间time_t now;struct tm* timeInfo;time(&now);timeInfo = localtime(&now);// 格式化时间字符串(包含年月日时分秒)char timeStr[64];strftime(timeStr, sizeof(timeStr), "%Y年%m月%d日 %H:%M:%S", timeInfo);// 清空画布(黑色填充)memset(timeBmp->map, 0, AREA_WIDTH * AREA_HEIGHT * 4);// 绘制文字到画布(白色文字)fontPrint(f, timeBmp, 10,  // 文字在画布内的X偏移60,  // 文字在画布内的Y偏移(基线位置)timeStr, getColor(255, 255, 255, 255),  // 白色文字AREA_WIDTH - 20  // 最大显示宽度(留边距));// 将画布显示到LCDshow_font_to_lcd(lcd->mp, TIME_X, TIME_Y, timeBmp);// 1秒刷新一次sleep(1);}// 资源释放(实际运行时循环不会退出,此处为代码完整性)destroyBitmap(timeBmp);fontUnload(f);lcdClose(lcd);return 0;
}

关键说明与问题排查

  • 楷体显示乱码
    • 原因:字符串编码非 GB2312,或simkai.ttf未正确加载。
    • 解决:确保源文件用 GB2312 编码保存,检查字库路径(用ls /usr/share/fonts/simkai.ttf验证)。
  • 文字重叠
    • 原因:未清空画布或 LCD 区域的旧数据。
    • 解决:每次刷新前用memset(bm->map, 0, ...)清空画布,或调用lcd_clear_area清空 LCD 对应区域。
  • 字体截断
    • 原因:画布宽度不足,或fontPrintmaxWidth设置过小。
    • 解决:时间字符串约 20 字符,48 号楷体需画布宽≥48×20=960(或调大maxWidth)。
  • 函数参数错误
    • fontSetSize无返回值,需确保font* f非空;
    • show_font_to_lcd的第一个参数必须是unsigned int*(与mmap返回值类型一致)。
  • 通过以上适配,可在嵌入式设备上使用楷体simkai.ttf正确显示中文及时间,兼顾美观与稳定性。

扩展:点阵字库与 TTF 字库对比

对比维度 点阵字库(如 16×16) TrueType 字库(.ttf)
存储方式 像素点阵数据 矢量曲线公式
缩放效果 固定分辨率,放大失真(锯齿) 任意缩放不失真
占用内存 小(16×16 字库约 6763×32 字节≈210KB) 较大(单个.ttf 约 1-5MB)
解码速度 快(直接映射像素) 较慢(需计算矢量曲线)
适用场景 小分辨率屏(OLED)、资源有限的嵌入式设备 大分辨率 LCD、需缩放字体的场景(如菜单)
开发复杂度 简单(直接操作点阵) 较复杂(需依赖字体库,如 FreeType)

根据项目需求选择字库:若显示简单、分辨率固定,选点阵字库;若需缩放、美观,选 TTF 字库。

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

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

相关文章

完整教程:突破NER性能瓶颈:BERT与LLM协同的混合架构实践

完整教程:突破NER性能瓶颈:BERT与LLM协同的混合架构实践2025-10-26 15:00 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important…

使用EasyBlogImageForTypora将Typora上传图床改为博客园——2025/10/26最新

使用Typora写作,图片即时同步到博客网站,无需第三方图床,写完可直接粘贴。支持网络图片上传。目前的使用方法和之前的教程有部分差异,所以重新写一篇使用说明 安装 EasyBlogImageForTypora 下载程序: https://git…

AVCodecContext,AVFormatContext区别

AVCodecContext,AVFormatContext区别1.AVFormatContext: 容器/流级别 核心信息: 封装格式(如.mp4,.mkv,.flv) 流的数量和类型 元数据(Metadata,如作者标题) 时长,比特率 I/O上下文(用于读写数据) 2.AVCodecCon…

题解:P5853 [USACO19DEC] Tree Depth P

题意:对于逆序对数为 \(k\) 的长为 \(n\) 的排列,建出笛卡尔树,求对于每个点 \(i\) 在所有树中的深度之和。 做法: 首先不考虑笛卡尔树的事情,我们只算满足条件的排列个数,这个是经典的可以 \(O(n^3)\) 解决的问…

2025 年 10 月门窗十大品牌综合实力权威推荐榜单,聚焦高端定制需求与全案交付能力

2025 年 10 月门窗十大品牌综合实力权威推荐榜单由中国建筑金属结构协会、全国工商联家具装饰业商会联合发布。本次榜单针对高端市场需求,以 “高端定制 + 全案交付” 为核心评选维度,突破传统评选框架:定制维度评估…

idea或pycharm工具报python packaging tools not found. install packaging tools

这时候,我们找到需要添加的解释器的位置,我这里是以自己添加的为例(位置是:D:\AdvancedSoftware\python3.13.2\install),点击进入这个目录,然后在目录栏输入cmd,并回车进入命令终端打开cmd窗口输入命令: 01:…

力扣 第473场周赛(A~D)

力扣 第473场周赛(A~D)$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");A:3726. 移除十进制表示中的所有零简单题,转str后去掉所有0。1 class Solution: 2…

Java学习与工作汇报总结

一、学习与工作概况 过去一年中,我系统学习了Java核心技术,并参与了多个项目开发实践。通过理论学习和实际应用,掌握了Java面向对象编程、集合框架、多线程、IO流等核心知识,同时熟悉了Spring Boot、MyBatis等主流…

Alibaba Cloud Linux 4 镜像备份到自己的 OSS 中,并同时使用该镜像部署

Alibaba Cloud Linux 4 镜像备份到自己的 OSS 中,并同时使用该镜像部署使用 OSS 直接存储镜像文件 #!/bin/bash# backup-to-oss.sh - 镜像备份到 OSS IMAGE_NAME="portainer/portainer-ce:latest"LOCAL_TAR=…

[K230学习笔记 02] I2C - Ze

硬件背景 I2C如下图所示,简单来说I2C是一种同步、串行、多主从的通信总线,由时钟线(SCL)与数据线(SDA)组成。在总线上的设备由一个唯一的地址识别,并且可以作为发送器或接收器运行,具体取决于设备的功能。图1.…

javascript 学习笔记(有c++基础)(更新中)

javascript 学习笔记(有c++基础)(更新中)javascript学习笔记 了解var 定义变量,可定义任何类型,若不用 var 则为全局变量 打印变量可以使用alert 或 console.log NaN这个值与其他不同,判断方法为 isNaN(NaN) 判断浮…

10.24总结

import java.util.*; import java.util.concurrent.TimeUnit; public class ArithmeticPractice { private Set generatedQuestions = new HashSet<>(); private List questions = new ArrayList<>(); pri…

《代码大全》读后感(1)

《代码大全》的开篇并未急于灌输编程技巧,而是先搭建了对“编程”这一行为的底层认知框架,这让我彻底摆脱了“代码只是指令集合”的浅层认知。书中将编程定义为“一项复杂的智力活动”,强调其兼具工程属性与艺术特质…

Function Calling

工作原理 Function Calling 通过在应用程序和大模型之间的多步骤交互,使大模型可以参考外部工具信息进行回答。https://help.aliyun.com/zh/model-studio/qwen-function-calling

20232302 2025-2026-1《网络与系统攻防技术》实验三实验报告

一.实验内容 (1)正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或技巧。 正确使用msf编码器,使用msfvenom生成如jar之类的其他文件 veil,加壳工具 使用C + shellcode编程(2)通过组合应用各种技术…

MCP Router使用学习

前言 最近在捣鼓使用 codex,由于 claude code 总是封号,就改用 codex 了,但是 codex 对于导入 mcp 有点麻烦,格式方式与之前不太相同,最近发现有个 mcp 集合工具,准备研究一下如何使用。 1. 为什么要用 MCP Rout…

fvm Flutter多版本管理安装与常用指令

一、安装pub.dev - fvmfvm 官方安装文档,包含各系统安装方式。也通过 Dart 包管理工具安装 FVM:$ brew tap leoafarias/fvm $ brew install fvm# 或$ dart pub global activate fvm环境变量配置建议,在 ~/.zshrc 或…

人生八要(摘抄)

大喜要稳;大怒要忍大惑要等;大悲要静大忙要慢;大闲要勤大富要俭;大穷要志最爱这句: 大惑要等不知道你现在在哪个阶段,希望你能体会其中道理

20232322 2025-2026-1 《网络与系统攻防技术》实验三实验报告

一.实验内容正确使用msf编码器,使用msfvenom生成如jar、php之类的其他文件,并用virustotal进行检测,会使用基本的免杀工具 通过组合应用各种技术实现恶意代码免杀 用另一电脑实测,在杀软开启的情况下,可运行并回连…

详细介绍:vb.net编写DDE(Dynamic Data Exchange)服务器

详细介绍:vb.net编写DDE(Dynamic Data Exchange)服务器pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…