C#开发RTF编辑器实战:基于RichTextBox的富文本处理与避坑指南
简介C#编写的RTF文档编辑器项目包面向Windows桌面应用学习者与初级开发者演示如何用C#和Windows Forms实现富文本文档的打开、保存与另存为。资源共37个文件压缩包仅90KB包含8个.cs源代码文件、Visual Studio解决方案与工程配置、可执行程序、PNG图标资源和调试缓存等目录结构紧凑便于对照工程原貌学习。已有345人浏览学习。通过带注释的源码可以梳理RichTextBox控件读写RTF文件、System.IO完成文件I/O、菜单与工具栏事件绑定、以及窗体设计器与逻辑代码分离等关键知识点同时.resx资源和图标文件展示了界面资源与多窗体的组织方式对理解一个简单的桌面文档编辑工具从界面到功能的完整实现很有实际参考价值。1. 用C#写RTF编辑器为什么RichTextBox够用又不够用市面上随手能找的富文本编辑器很多但在内网OA、老旧系统升级、专用文档工具这类场景里RTF格式的兼容性一直没人能替代。C#做RTF文档编辑器核心思路并不复杂用WinForms自带的RichTextBox控件完成RTF的读写和编辑交互再叠加工具栏、格式控制、文件处理这些外围能力最终交付一个能用的文档工具。RichTextBox本身对RTF 1.6规范的支持比较完整小步快跑地搭一个能用、能改、能扩展的编辑器是现实可行的。本文按一个可交付的路线来写先搭骨架再补格式按钮最后处理剪贴板、编码、缩放这些容易翻车的细节。2. 搭建编辑器骨架从窗体到RTF读写的最小闭环2.1 选型为什么用RichTextBox而不是第三方控件做RTF编辑器的第一个分歧点是用WinForms自带的RichTextBox还是引入第三方富文本控件。我的建议是如果需求是“能编辑RTF、能设置基本格式、能保存为RTF/doc”先老老实实用RichTextBox。RichTextBox的底层封装了微软的RichEdit控件对RTF 1.6以下版本的读写是原生的不需要解析RTF语法也不用自己做文本布局。第三方控件的好处是外观现代、功能多但代价是要么商业授权要么需要花大量时间适配中文字体、输入法、打印分页。更现实的问题是很多第三方的“RTF支持”实际是把RTF转成HTML再渲染转来转去格式必然有损。RichTextBox也远非完美它最典型的问题是对中文标点的排版处理粗糙对图片只支持嵌入位图表格支持等于没有。但这些缺陷可以通过外围手段弥补不影响它作为RTF编辑器内核的价值。2.2 最小骨架工具栏、编辑区、状态栏三段式布局我做一个WinForms的RTF编辑器习惯按三段式布局来组织窗体顶部ToolStrip放格式操作按钮中间DockFill的RichTextBox作为编辑区底部StatusStrip显示行号、字数、编码信息。这个结构对应实际使用频率最高的操作路径也方便后续扩展查找替换、字数统计这类功能。public partial class RtfEditorForm : Form { private RichTextBox _rtb; private ToolStrip _toolbar; private StatusStrip _statusBar; public RtfEditorForm() { InitializeComponent(); BuildLayout(); WireEvents(); } private void BuildLayout() { _rtb new RichTextBox { Dock DockStyle.Fill, AcceptsTab true, // Tab键作为缩进输入而不是切换焦点 DetectUrls true, // 自动识别URL并显示为可点击样式 WordWrap true, // 默认自动换行长文档可切换 ScrollBars RichTextBoxScrollBars.Both }; _toolbar new ToolStrip(); _statusBar new StatusStrip(); _toolbar.Items.Add(new ToolStripButton(打开) { Tag Open }); _toolbar.Items.Add(new ToolStripButton(保存) { Tag Save }); _toolbar.Items.Add(new ToolStripSeparator()); _toolbar.Items.Add(new ToolStripButton(加粗) { Tag Bold }); Controls.Add(_rtb); Controls.Add(_toolbar); // ToolStrip默认DockTop Controls.Add(_statusBar); // StatusStrip默认DockBottom } }这段代码的关键不是把控件堆上去而是Dock顺序。WinForms的Dock布局遵循“后添加的先占位”规则所以必须先Add(_rtb)再Add(_toolbar)否则工具栏会把编辑区挤到一边。AcceptsTab true必须显式设置默认Tab键会在控件间跳焦点写文档时按Tab缩进会变成焦点跳走这个体验问题很容易被忽略。DetectUrls会让RTB把URL自动渲染成蓝色下划线但要注意这也会把你粘贴的纯文本路径误判成链接内网环境尤其明显。如果不需要直接保持默认false即可。2.3 打开和保存Rtf、Text、SelectedRtf三者的区别打开和保存是最容易出问题的环节。RichTextBox暴露了三个跟内容相关的属性Text、Rtf、SelectedRtf。三者的语义完全不同用错一个都会造成内容丢失或格式错乱。Text纯文本读取时去掉所有格式写入时按纯文本处理。Rtf整个文档的RTF源码包含格式信息是保存和加载RTF文件的正确路径。SelectedRtf当前选中区域的RTF源码范围裁剪、局部复制用这个。private void OpenRtfFile(string path) { if (!File.Exists(path)) return; using (var fs new FileStream(path, FileMode.Open, FileAccess.Read)) { _rtb.LoadFile(fs, RichTextBoxStreamType.RichText); } } private void SaveRtfFile(string path) { // 扩展名是.txt时按纯文本保存是.rtf或.doc时按RTF保存 var ext Path.GetExtension(path).ToLowerInvariant(); if (ext .txt) { File.WriteAllText(path, _rtb.Text, Encoding.UTF8); } else { using (var fs new FileStream(path, FileMode.Create, FileAccess.Write)) { _rtb.SaveFile(fs, RichTextBoxStreamType.RichText); } } }LoadFile的第二个参数决定了解析方式。RichTextBoxStreamType.RichText按RTF语法解析PlainText按纯文本解析。判断一个文件到底是RTF还是纯文本不要看扩展名要看文件开头是不是{\rtf1。很多从网页复制出来的内容实际是带格式的HTML转存文本扩展名是.txt但里面塞满了RTF控制字。保存同理。用户把文件保存为.docWord确实能打开但.doc是二进制格式RichTextBox保存的其实还是RTF内容只是扩展名改了。Word足够宽容能识别但如果你把这个文件发给别人用WPS打开就可能出现格式解析异常。这就是为什么保存对话框里的文件类型过滤器不要让用户乱选。3. 工具栏与格式控制把RTF控制字变成可点的按钮3.1 字体和字号SelectionFont的边界字体设置通过SelectionFont属性完成。这个属性是一个Font对象设置时会整体替换选中区域的字体属性。常见的错误写法是只改SelectionFont.Name或只改SelectionFont.Size但属性本身没有提供单独的setter你必须构造一个新的Font对象。private void ApplyFontFamily(string familyName) { if (_rtb.SelectionLength 0) { // 没有选中内容时设置的是后续输入文本的字体 _rtb.SelectionFont new Font(familyName, _rtb.Font.Size); return; } var current _rtb.SelectionFont; _rtb.SelectionFont new Font( familyName, current ! null ? current.Size : _rtb.Font.Size, current ! null ? current.Style : FontStyle.Regular ); }字体设置有一个容易忽略的行为当选中区域包含多种字体时SelectionFont返回null。所以读取当前字体时必须先做null判断否则直接访问SelectionFont.Name会抛NullReferenceException。字号设置同理也不要在现有Font上直接改Size属性。Font对象的属性是只读的必须新建。字体大小建议用float类型但不同字体在RichTextBox里的渲染高度不一致同一字号切换字体后视觉大小会明显变化这是字体度量本身决定的不是代码问题。3.2 加粗、斜体、下划线Toggle逻辑的正确打开方式格式开关按钮的核心逻辑是“读取当前状态取反后应用”。RichTextBox提供了SelectionFont.Style来判断当前是否加粗但和字体名称一样多格式混排时返回的SelectionFont可能是null。private void ToggleBold() { if (_rtb.SelectionLength 0) return; var current _rtb.SelectionFont; if (current null) { // 混排区域保守处理默认改为非加粗避免误伤 _rtb.SelectionFont new Font(_rtb.Font, FontStyle.Regular); return; } var newStyle current.Style; if (current.Bold) newStyle ~FontStyle.Bold; // 去掉Bold位 else newStyle | FontStyle.Bold; // 加上Bold位 _rtb.SelectionFont new Font(current.FontFamily, current.Size, newStyle); }这里的位运算写法比if/else赋值更可靠因为FontStyle是[Flags]枚举直接赋值会丢掉其他样式。比如一段文本同时是加粗和斜体想取消加粗如果写成new Font(family, size, FontStyle.Regular)斜体也被一起干掉了。用位运算能精确控制单个样式位。按钮的按下状态也要跟着光标位置实时刷新。RichTextBox的SelectionChanged事件里做一次状态同步否则用户把光标移到一段加粗文字中间工具栏按钮还保持弹起状态用户会误以为加粗没生效。3.3 颜色与高亮ColorDialog的两个坑字体颜色用SelectionColor背景高亮用SelectionBackColor这俩都是Color结构直接赋值即可。但用ColorDialog时有两个坑。第一个坑是ColorDialog默认的FullOpen属性为false展开自定义颜色面板需要手动设置。第二个坑是ColorDialog会返回Color的Name属性为“ff000000”这类ARGB字符串直接存文件没问题但如果要跟RTF控制字映射需要用ColorTranslator.ToWin32转成BGR整数值。private void ApplyForeColor() { using (var dlg new ColorDialog()) { dlg.FullOpen true; // 展开完整调色板 dlg.AnyColor true; // 允许选择任意颜色 if (dlg.ShowDialog() ! DialogResult.OK) return; _rtb.SelectionColor dlg.Color; } }设置背景色时注意SelectionBackColor在RichTextBox里作用于选中区域的背景视觉上就是荧光笔效果。但RTF规范里背景色和字体颜色的存储方式不同背景色存到\highlight控制字里如果目标RTF文件要兼容Word的老版本\highlight的色值表只有16种预定义色超出范围的颜色会被降级。3.4 段落对齐与缩进SelectionParagraphFormat的不对称问题对齐和缩进通过SelectionAlignment和SelectionIndent控制。对齐是枚举赋值比较简单。缩进用的是像素值不是厘米也不是字符数这个单位差异会导致不同DPI显示器下同一文档的缩进看起来不一样。private void SetParagraphFormat() { // 左缩进2厘米约等于 2 / 2.54 * 96 ≈ 76像素 _rtb.SelectionIndent 76; // 首行缩进2字符按当前字号估算 var fontSizePx _rtb.SelectionFont ! null ? _rtb.SelectionFont.Size * 96f / 72f : _rtb.Font.Size * 96f / 72f; _rtb.SelectionFirstIndent (int)(fontSizePx * 2); }SelectionIndent是左缩进SelectionFirstIndent是首行缩进SelectionRightIndent是右缩进。首行缩进这个值特别坑它表示的是相对于SelectionIndent的偏移量正数代表向右缩进负数代表悬挂缩进配成正负理解错段落格式就全乱了。另外SelectionParagraphFormat这个属性在WinForms里没有暴露给用户要精确设置行距、段前段后距只能操作SelectionCharFormat或直接改RTF源码。做基本编辑器不需要碰这个层面。4. RTF编辑器落地避坑剪贴板、编码、缩放与另存为4.1 剪贴板粘贴丢格式DataFormats.Rtf与WinForms的格式协商从Word或网页复制内容粘贴到RichTextBox格式基本能保留但反过来把RichTextBox的内容粘贴到记事本再复制回来格式就全丢了。这是因为系统剪贴板里多份数据格式并存目标程序按自己认识的格式取。RichTextBox弹出右键菜单选择“粘贴”时如果剪贴板里既有HTML又有RTF还有纯文本WinForms默认取哪份是个黑匣子。private void PasteWithFormat() { if (!Clipboard.ContainsData(DataFormats.Rtf)) return; var dataObject Clipboard.GetDataObject(); if (dataObject null) return; if (dataObject.GetDataPresent(DataFormats.Rtf)) { var rtfData dataObject.GetData(DataFormats.Rtf) as string; if (!string.IsNullOrEmpty(rtfData)) { _rtb.SelectedRtf rtfData; // 保留格式插入 return; } } // 降级没有RTF数据时退回纯文本粘贴 if (dataObject.GetDataPresent(DataFormats.Text)) { _rtb.SelectedText dataObject.GetData(DataFormats.Text) as string; } }SelectedRtf是插入RTF内容到光标位置的正确入口它会替换当前选中区域。直接给Rtf赋值会替换整个文档这俩的差异是最容易翻车的地方。4.2 读RTF变乱码编码探测与流式加载RTF文件本身是文本文件但其中的编码可能是ASCII、ANSI、Unicode或UTF-8。用LoadFile方法时底层会按RTF头部的\ansicpg控制字决定代码页。麻烦的是很多老系统生成的RTF头不完整或者头部声明与实际内容编码不一致。private void SafeLoadRtf(string path) { byte[] header new byte[4]; using (var fs File.OpenRead(path)) { fs.Read(header, 0, 4); } Encoding enc Encoding.Default; if (header[0] 0xFF header[1] 0xFE) enc Encoding.Unicode; // UTF-16 LE带BOM else if (header[0] 0xEF header[1] 0xBB header[2] 0xBF) enc Encoding.UTF8; // UTF-8带BOM else if (header[0] 0x0D || header[0] 0x7B) enc Encoding.Default; // 以{\rtf开头按系统ANSI处理 // 统一按字节流读入手动转字符串后赋值 string content File.ReadAllText(path, enc); _rtb.Rtf content; }用Encoding.Default在中文Windows上是GBK但这只适合“系统ANSI”场景。我一般建议如果文件头部有\ansicpg936直接按GBK解码如果有\ansicpg1252按Latin-1解码。不要迷信File.ReadAllText的自动检测它在没有BOM时默认UTF-8对老RTF文件是灾难。4.3 高DPI屏幕上字体模糊AutoScaleMode与RTF字体的换算Windows窗体在高DPI显示器下默认缩放但RichTextBox内部保存的RTF字体大小是“半磅”单位缩放时WinForms只拉伸控件不重新计算RTF里的字号值结果就是界面控件清晰但编辑区字体明显发虚。public RtfEditorForm() { AutoScaleMode AutoScaleMode.Dpi; // 在PerMonitorV2模式下需要手动处理字体缩放 _rtb.Font new Font(_rtb.Font.FontFamily, 10.5f); }更稳妥的做法是在Form_Load里读取DeviceDpi如果大于96把所有RTF里能设置的格式值重新换算一遍。这个操作没有标准API常见思路是遍历所有段落读取SelectionFont.Size乘以DPI比例重新构造Font。文档不大时性能可以接受但如果是几百页的长文档建议不要批量处理。4.4 另存为.doc后Word打开报错保存格式与扩展名匹配做编辑器必定会遇到用户要求“能存成Word文档”。RichTextBox不支持真正的.doc二进制格式SaveFile方法即使你传.doc扩展名写入的仍然是RTF内容。Word打开时能自动识别但如果文件里包含复杂的表格或嵌入对象Word会提示“文件格式与扩展名不匹配是否打开”。更隐蔽的问题是如果保存对话框的Filter里同时有.rtf和.doc用户选了.doc你按RTF格式写入文档在WPS里打开就变纯文本了。解决思路是保存前根据扩展名判断如果确实是.doc要么明确告诉用户“当前导出的是RTF兼容内容建议用Word另存”要么引入一个真正的Word导出组件。我一般会做两层界面上默认Filter只留.rtf和.txt把.doc选项放在“另存为”而不是“保存”里并且在另存为.doc时弹一个提示框说明实际输出的是RTF内容。4.5 撤销栈的局限性程序化修改不进Undo队列RichTextBox的Undo()只能撤销用户在界面上直接输入或格式化的操作。通过代码修改Rtf、SelectionColor、SelectionFont等属性所做的改动不会进入内置撤销栈。这在做“一键格式化”功能时特别坑用户点了按钮然后按CtrlZ想撤销结果纹丝不动。实测中SelectionFont赋值有时能进撤销栈有时不能行为不一致。比较可靠的方案是每次做批量格式修改前把完整RTF存到一个自定义栈里手动实现撤销。private Stackstring _undoStack new Stackstring(); private void PushUndoSnapshot() { _undoStack.Push(_rtb.Rtf); if (_undoStack.Count 50) // 限制栈深度防内存暴涨 { var list _undoStack.ToList(); list.RemoveAt(list.Count - 1); _undoStack new Stackstring(list); } } private void UndoCustom() { if (_undoStack.Count 0) return; _rtb.Rtf _undoStack.Pop(); }注意_rtb.Rtf的赋值会触发TextChanged事件如果你的代码里在TextChanged里做了状态同步这个赋值会引发递归。进栈和撤销操作里要加锁标志避免重复压栈。5. 进阶书签跳转、控件封装、长文档优化与中文排版5.1 书签跳转用书签域实现文档内导航RTF规范支持书签对应的控制字是{\*\bkmkstart 名称}和{\*\bkmkend 名称}。RichTextBox不直接暴露书签API但可以通过查找这些控制字配合SelectionStart实现跳转。这个方法不优雅但胜在不动底层。private bool JumpToBookmark(string name) { string pattern \{\\?\*\bkmkstart name \}; int pos _rtb.Text.IndexOf(name, StringComparison.Ordinal); if (pos 0) return false; // 直接搜索控制字不可靠改为扫描Rtf源码定位书签位置 string rtf _rtb.Rtf; int idx rtf.IndexOf(\\bkmkstart name, StringComparison.Ordinal); if (idx 0) return false; // 从Rtf源码位置反推文本位置截取前缀统计纯文本长度 string prefix rtf.Substring(0, idx); _rtb.Select(prefix.Length, 0); _rtb.ScrollToCaret(); return true; }这个反推方法有个误差RTF源码里转义符和分组符占的字符数会被计入prefix.Length导致定位偏差。精度要求高的场景需要真正解析RTF语法计算\bkmkstart之前的不可见控制字占位。一般文档编辑器里书签跳转的精度到段落级就够用了。5.2 封装成UserControl让编辑器成为可复用组件如果把编辑器做成产品一定要从一开始就封装成UserControl而不是直接写在Form里。封装的关键是暴露稳定的属性、方法和事件把RichTextBox的细节藏起来。public partial class RtfEditorControl : UserControl { private RichTextBox _rtb; // 对外暴露文档内容 public string DocumentRtf { get _rtb.Rtf; set _rtb.Rtf value; } public string DocumentText { get _rtb.Text; set _rtb.Text value; } // 对外事件内容变更 public event EventHandler DocumentChanged; public void LoadRtfFile(string path) { /* 内部实现 */ } public void SaveRtfFile(string path) { /* 内部实现 */ } public bool Undo() { return _rtb.Undo(); } // 工具栏按钮通过方法调用不直接访问控件 public void ToggleBold() { /* 内部实现 */ } public void ApplyFontFamily(string name) { /* 内部实现 */ } }这样封装的价值在于以后不管换皮肤、加功能、换底层实现外部调用方的代码不用改。比如未来要把RichTextBox换成第三方控件只要保持DocumentRtf和那些Toggle方法签名不变上层工具栏和文件菜单就不受影响。5.3 长文档卡顿延迟刷新与局部更新策略RichTextBox处理几千行的小文档没问题但上万行或包含大量图片时输入和格式化会有明显卡顿。实测中格式化整个文档比输入文本更消耗性能因为每次SelectionFont赋值都会触发整个控件的重绘。缓解方法有几个。第一操作前调用_rtb.SuspendLayout()操作完成后调用ResumeLayout()。第二批量格式化时分段commit每处理100个段落调用一次Application.DoEvents()防止界面假死。第三如果只是改全文字体而内容不长直接改_rtb.Font比遍历所有段落设置SelectionFont快得多。图片多的文档建议用RichTextBoxStreamType.RichNoOleObjs保存这个枚举值在保存时会丢弃OLE对象只保留文本和格式文件体积能显著下降。5.4 输入法与中文排版两个东亚字符特有的细节中文用户绕不开的两个问题一是ImeMode设置二是全角半角标点。RichTextBox的ImeMode默认是NoControl在中文输入法下按快捷键或切换输入法时有时会出现候选框位置错乱。把ImeMode设为On能改善但会让英文输入法下也弹输入法所以更合理的做法是让用户通过快捷键手动切换。中文排版方面RTF的\kerning控制字控制字符间距调整Word默认开启但RichTextBox默认关闭。开启方式没有公开API只能改RTF源码里的\kerning值。实用层面上我建议中文文档不要过度依赖锐化技术设置合适的首行缩进和行距更重要。行距通过修改RTF源码中的\sl控制字实现RichTextBox属性面板里没有直接入口。我从做第一个RTF编辑器版本得到的教训是不要试图在一个版本里做完所有功能先保证“打开-编辑-保存-格式设置”这条主链路不出错剪贴板、编码、撤销这些边角功能单独排期。编辑器类工具用户真正每天用的功能就那么五六个把核心路径打磨顺了比堆功能有用得多。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

开源组件搭建轻型AI中台:解决企业重复录入与对账难题

开源组件搭建轻型AI中台:解决企业重复录入与对账难题

上个月我帮一家做建材供应链的公司做收尾交付,财务总监跟我聊起以前每个月月底的状态:十几个Excel在四个人手里传来传去,销售部录入的订单在ERP、CRM、订料系统里永远差那么几条,银行回单和对账单对不上几乎是常态,月底…

2026/10/14 9:10:12 阅读更多 →
Redis单线程为何能支撑十万QPS?epoll事件循环与原子性解析

Redis单线程为何能支撑十万QPS?epoll事件循环与原子性解析

1. 一个反直觉的事实:单线程Redis为何能跑赢多线程服务先扔一个结论:我最早接触Redis时也以为"单线程低性能"是常识。毕竟Java、Go这边张口就是线程池、并发模型,Nginx也在搞多进程,为什么偏偏Redis坚持单线程&#xff…

2026/10/14 17:21:49 阅读更多 →
微网两阶段鲁棒经济调度与CCG算法MATLAB实现

微网两阶段鲁棒经济调度与CCG算法MATLAB实现

1. 为什么微网调度要从"确定性"走向"两阶段鲁棒"1.1 一次光伏骤降让确定性调度直接翻车去年年底我在做一个园区级微网的日前经济调度项目,碰到的第一个问题就非常典型:光伏和风电的预测曲线在早上看起来非常漂亮,预测中午…

2026/10/15 3:02:39 阅读更多 →

最新新闻

JMeter 5.6.2压力测试实战:从线程组到报告解读

JMeter 5.6.2压力测试实战:从线程组到报告解读

简介:Apache JMeter 5.6.2 是由 Apache 组织维护的开源纯 Java 压力测试工具,具备跨平台特性,可运行于 Windows、Linux、macOS。其用途在于模拟大量用户并发访问,评估 Web 应用、数据库、FTP 服务器等静态与动态资源的高并发稳定性…

2026/10/15 20:26:01 阅读更多 →
STM32F3开发基座解析:HAL嫁接、ADC同步与OPAMP避坑指南

STM32F3开发基座解析:HAL嫁接、ADC同步与OPAMP避坑指南

简介:本资源是ST官方发布的STM32F3系列微控制器HAL封装库完整固件包(V1.11.0),面向嵌入式初学者、STM32课程学习者及F3平台项目开发者,解决底层驱动适配难、外设配置复杂、代码可移植性差等典型开发痛点。压缩包共2000…

2026/10/15 20:26:01 阅读更多 →
HART主站协议栈实现:嵌入式C语言轻量级开源方案

HART主站协议栈实现:嵌入式C语言轻量级开源方案

简介:本资源是一份面向工业自动化领域嵌入式开发者与协议栈学习者的HART主设备协议栈开源实现,聚焦于HART(Highway Addressable Remote Transducer)通信标准在软件层面的落地,解决智能仪表系统中主控端(如P…

2026/10/15 20:26:00 阅读更多 →
BMN时序动作定位原理:边界匹配网络的矩阵建模与工业落地

BMN时序动作定位原理:边界匹配网络的矩阵建模与工业落地

1. 项目概述:为什么BMN不是又一个“边界检测”模型,而是时序动作定位的范式跃迁BMN(Boundary Matching Network)这个标题乍看平平无奇,像极了CV领域里那些堆叠卷积、加个注意力就起名“XX-Net”的常规操作。但如果你真…

2026/10/15 20:26:00 阅读更多 →
INCA_ProF脚本自动化标定:从执行模型到批量标定与报告生成

INCA_ProF脚本自动化标定:从执行模型到批量标定与报告生成

简介:这份PDF面向汽车电子标定工程师与INCA初学者,系统梳理ProF脚本的编程要点,帮助读者理解如何用脚本定制ECU闪存编程与自动化任务。资源为单文件PDF,压缩包约271KB,内容以图文笔记形式呈现,便于随时查阅…

2026/10/15 20:26:00 阅读更多 →
Advanced Installer 15.2汉化实践:Windows安装包多语言工程化落地

Advanced Installer 15.2汉化实践:Windows安装包多语言工程化落地

简介:Advanced Installer 15.2汉化版是一款面向Windows平台开发者与系统管理员的专业级安装包制作工具,解决传统MSI打包流程复杂、本地化支持弱、跨环境部署兼容性差等痛点,适用于.NET、Java、SQL Server等多技术栈项目的自动化部署场景。资源…

2026/10/15 20:24:58 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →