Qt QFile文件读写深入解析:模式、编码、性能与踩坑实战
1. 项目概述从一个踩坑场景聊起先说说我为什么想写这篇文章。前阵子接了个活帮某开发者的一个文本解析工具做性能优化里面有个环节是把几个配置文件读进来、改完再写回去。代码本身看着没毛病QFile file(path); file.open(QIODevice::ReadOnly);读完close()写的时候再Open(QIODevice::WriteOnly)一套流程走下来。但是在Windows平台上用一段时间后用户反馈说配置文件偶尔会丢内容甚至整个文件变成0字节。排查到最后问题出在几个非常容易被忽略的细节上一是open()之后没判断返回值就直接读二是写文件时没考虑文件被其他进程占用的情况三是关闭文件前没调用flush()。这三兄弟凑在一起文件读写这事就翻车了。从那时候起我就意识到QFile看似简单但真要写出稳如老狗的代码里面门道不少。这篇文章打算把所有跟QFile读写相关的知识点摊开来讲透核心概念、打开模式、读写细节、编码处理、性能对比、异常恢复、常见坑位。适合刚接触Qt的初学者建立完整认知也适合写过一阵子但没系统梳理过文件操作的老手查漏补缺。看完之后你能掌握一套可以直接抄进项目里的文件读写最佳实践。2. 核心细节解析QFile的打开模式你真的搞懂了吗2.1 打开模式背后的位运算逻辑QFile的打开模式用QIODevice::OpenModeFlag枚举表示很多人习惯只记ReadOnly和WriteOnly两个词儿就开始写代码但这里面的组合关系其实非常讲究。QFile file(example.txt); file.open(QIODevice::WriteOnly | QIODevice::Text);这个|符号是位或操作表示多个标志位可以同时生效。常用的标志位包括ReadOnly以只读方式打开文件必须存在否则open失败WriteOnly以只写方式打开如果文件不存在会尝试创建ReadWrite可读可写文件不存在时某些操作系统上可能创建失败Append追加模式所有写入内容自动放到文件末尾Truncate打开时清空文件原有内容Text文本模式Windows上会把\n自动转换成\r\nNewOnly仅当文件不存在时才创建成功Qt 5.11新增ExistingOnly仅当文件已存在时才打开成功Qt 5.11新增注意WriteOnly、Append、Truncate这三者的关系。WriteOnly | Truncate是最常见的“覆盖写”组合目标文件内容直接清空从头写。而WriteOnly | Append则是“追加写”。如果只写Append不写WriteOnly有些情况下打开也会失败保险起见是两个一起加。这里的核心要点是QFile本身没有单独的“创建文件”模式创建行为是WriteOnly带来的副作用——文件不存在时自动创建。但是如果父目录不存在WriteOnly一样会失败需要额外用QDir().mkpath()先把目录建好。2.2 文本模式与二进制模式的本质区别文件操作里有个经典问题什么时候用Text标志什么时候不用。在Unix/Linux/macOS上Text标志其实没什么实际作用因为换行符统一是\n。但在Windows上文本文件用\r\n作为换行符。如果以二进制模式打开Qt读写时就原样处理字节当你写入\n时文件里就真的只有一个0x0A这在Windows记事本里打开会错乱成一行但如果加了Text标志Qt会自动帮你做\n到\r\n的转换。反过来读文件时Text模式会把\r\n统一转成\n方便你按行处理逻辑。所以如果你写的是一个跨平台工具且处理的是纯文本数据强烈建议加上Text标志。但如果你在解析二进制文件格式比如图片、压缩包、自定义二进制协议千万别加Text否则一个0x0D 0x0A的字节序列可能被错误转换直接导致解析崩盘。我自己常用的判断标准文件最终是给人看的用Text文件最终是给程序解析的不用。3. 实操过程与核心环节实现3.1 经典读文件三种方式逐个实测一次性读入内存最直观的方式是用readAll()一次性把整个文件读进QByteArray。对于几MB的配置文件、小图片这类场景简单直接代码看着清爽。QFile file(config.ini); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() 打开文件失败: file.errorString(); return; } QByteArray data file.readAll(); file.close(); // 处理data这种方式的问题也明显文件太大时内存占用跟着涨。我做过一个测试读取一个1GB的日志文件readAll()瞬间吃掉接近1GB的内存加上中间拷贝的开销直接在32位程序里就爆了。按行读取处理日志、配置文件这类文本时按行读是性能与内存的平衡点。用QTextStream按行处理是常规操作也可以在底层用readLine()。QFile file(app.log); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } while (!file.atEnd()) { QByteArray line file.readLine(); // 去掉结尾换行符 line.chop(2); // 可能包含 \r\n processLine(line); } file.close();这里有个经验如果文件行数特别多比如几十万行用while (!file.atEnd())循环是没问题的atEnd()不会每次都去查文件大小性能开销可以忽略。指定大小分块读取大文件按固定大小分块是更稳的做法每一块处理完就丢弃内存还能顺便做进度条。QFile file(huge_data.bin); if (!file.open(QIODevice::ReadOnly)) { return; } const qint64 chunkSize 64 * 1024; // 64KB while (!file.atEnd()) { QByteArray chunk file.read(chunkSize); processChunk(chunk); }实测下来64KB到1MB之间的分块大小在机械硬盘、SSD、网络磁盘上综合表现都不错。分块太小比如4KB会导致系统调用次数暴增分块太大又跟readAll()一样有内存压力。3.2 经典写文件覆盖、追加、原子写覆盖写QFile file(output.txt); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { return; } file.write(第一行\n); file.write(第二行\n); file.flush(); // 把缓冲区数据落盘 file.close();很多人不知道flush()是干什么的。write()之后数据不一定立刻写到磁盘而是先存在Qt的缓冲区或者操作系统的页缓存里。如果不调用flush()直接close()close内部会做flush所以问题不大但如果程序在close之前崩溃缓冲区里的数据就丢了。所以关键数据写完立刻flush是个好习惯。追加写QFile file(log.txt); if (!file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { return; } file.write(新增的日志\n); file.close();用Append模式时写入位置自动定位到文件末尾。这里有个细节如果之前是用WriteOnly | Append打开但写入之前文件被别人删除了写入会重新创建文件。这在多进程日志系统中可能会引起困扰——两台机器同时写一个日志文件通过共享目录难免有竞争问题。原子写文件写到一半程序崩溃留下半个文件的垃圾——这种问题在配置文件场景下不能忍。最佳实践是“先写临时文件再替换目标文件”。大致的套路是把内容写到同一个目录下的临时文件写完flush并close然后用QFile::rename()替换目标文件。但我必须得说QFile::rename()在Windows上有一个经典坑如果目标文件已存在rename很有可能直接失败。QFile tmpFile(config.ini.tmp); // 写入完整内容 tmpFile.write(content); tmpFile.flush(); tmpFile.close(); // 先删除旧文件再重命名 QFile::remove(config.ini); if (!QFile::rename(config.ini.tmp, config.ini)) { qWarning() 替换文件失败; }这种方式的成本是两个文件名之间存在一个短暂窗口期旧文件被删了但新文件还没就位。如果对这点时间敏感就得引入更复杂的文件锁机制。不过对于大多数桌面工具场景这个方案已经比直接原地写安全太多了。3.3 QTextStream与编码处理乱码的根源QFile访问的是原始字节而文本文件是有编码的。直接用file.write()写中文字符串以UTF-8编码写入但如果对方的程序按GBK去读就乱码了。用QTextStream可以显式控制编码。QFile file(note.txt); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return; } QTextStream out(file); out.setEncoding(QStringConverter::Utf8); // Qt 6写法 out 你好Qt Qt::endl;在Qt 6中编码设置从setCodec改成了setEncoding。Qt 5用的是setCodec(UTF-8)老项目迁移时经常在这里报错。如果源文件是GBK编码读取时指定一下QTextStream in(file); in.setEncoding(QStringConverter::System); QString line in.readLine();这里的System表示系统本地编码在简体中文Windows下就是GBK/GB18030。如果你明确知道目标文件是UTF-8就直接设QStringConverter::Utf8。有一个很隐蔽的UTF-8问题BOM字节序标记。UTF-8文件的BOM是EF BB BF三个字节。QTextStream默认会自动跳过UTF-8的BOM但如果你用readAll()拿到的QByteArray是带BOM的直接QString::fromUtf8()会解析出开头一个看不见的\ufeff字符。处理方式QByteArray raw file.readAll(); if (raw.startsWith(\xEF\xBB\xBF)) { raw.remove(0, 3); } QString text QString::fromUtf8(raw);3.4 文件信息的获取与遍历QFile继承自QFileDevice继承了QFileInfo相关的文件状态查询能力。很多场景下我们不只是读写文件还要判断它存不存在、多大、什么时候改的。QFileInfo info(data.bin); if (info.exists()) { qint64 size info.size(); QDateTime lastModified info.lastModified(); bool isWritable info.isWritable(); }注意这里QFileInfo和QFile的区别。QFile是操作句柄QFileInfo是文件元数据。每次构造QFileInfo都会查询一次文件系统状态如果你在一个循环里反复检查同一个文件的状态可以复用同一个QFileInfo对象或者调用info.refresh()重新加载。目录遍历方面QDir的entryList()或者QDirIterator是主流方案。QDirIterator的优势在于处理超大目录时不会一次性把所有文件名读进内存是按需迭代的。QDirIterator it(/path/to/dir, QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories); while (it.hasNext()) { QString filePath it.next(); processFile(filePath); }3.5 二进制读写与字节序处理二进制文件时最核心的问题是字节序大小端。Qt提供了QDataStream来处理带类型的二进制读写默认使用大端序Big Endian这是网络字节序标准。QFile file(model.dat); if (!file.open(QIODevice::WriteOnly)) { return; } QDataStream out(file); out.setVersion(QDataStream::Qt_6_5); out (qint32)42; out (double)3.14; out QString(hello);相应的读取代码QFile file(model.dat); if (!file.open(QIODevice::ReadOnly)) { return; } QDataStream in(file); in.setVersion(QDataStream::Qt_6_5); qint32 num; double d; QString str; in num d str;这里setVersion非常重要。QDataStream在不同Qt版本之间序列化格式并不完全兼容老版本写入的文件新版本如果版本号设置不对读取时数据会错乱。如果你在维护一个老项目务必搞清楚当初写入时用的Qt版本。如果不想用QDataStream只读写原始字节可以用read()配合QByteArray手动解析但那就得自己处理字节序了quint32 leValue 0; file.read(reinterpret_castchar*(leValue), 4); // 如果文件是小端序而当前机器是大端序需要转换 quint32 hostValue qFromLittleEndian(leValue);这段代码里有个细节reinterpret_castchar*(leValue)读取原始字节放到一个quint32变量的内存里再用qFromLittleEndian做字节序转换。这种方式在嵌入式开发、自定义协议解析中非常常用。4. 工具选型解析QFile的同门师兄弟们4.1 QFile vs QSaveFile安全写的官方方案Qt其实提供了一个比“临时文件rename”更优雅的官方方案QSaveFile。它是专门为“原子保存”设计的类内部自动把内容写入同目录的临时文件提交时才真正替换目标文件。QSaveFile file(config.ini); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return; } file.write(content); if (!file.commit()) { qWarning() 保存失败; }核心区别在于如果写的过程中程序崩溃目标文件保持原样而用QFile::WriteOnly | Truncate这种方式文件已经被清空或者写了一半。所以在所有“配置文件保存”“用户文档保存”这类场景QSaveFile应该是第一选择。4.2 QFile vs QBuffer内存中的“伪文件”QBuffer不涉及磁盘它在内存里模拟文件操作接口。QByteArray data; QBuffer buffer(data); buffer.open(QIODevice::WriteOnly); buffer.write(hello); buffer.close(); // data 现在是 hello这种“伪文件”非常适合做数据格式转换把一段内存数据交给一个期望QIODevice接口的函数处理。举个例子某个压缩函数接受QIODevice*你想压缩一个小字符串可以直接用QBuffer包一层省得先写临时文件。4.3 QFile vs QTemporaryFile临时文件的正确姿势临时文件到处乱建是Windows系统里的灾难。QTemporaryFile会自动在系统临时目录创建唯一命名的文件析构时自动删除省得你手动清理QTemporaryFile tmpFile; if (tmpFile.open()) { tmpFile.write(临时数据); QString fileName tmpFile.fileName(); // 拿到临时路径 tmpFile.flush(); } // 作用域结束临时文件自动删除有两个细节值得注意QTemporaryFile默认是写在系统临时目录的如果系统临时目录权限受限创建会失败这时可以指定setFileTemplate()换目录另外临时文件默认以隐藏方式处理在某些同步软件同步临时目录时会有诡异行为不过那是另一个话题了。5. 性能优化与踩坑排查实录5.1 性能对比readAll vs 分块 vs QTextStream我在某开发者的测试项目里做过一组简单基准测试读取一个约200MB的文本文件结果大致如下不同硬件和Qt版本有差异趋势一致方式耗时内存峰值适用场景readAll一次读完约450ms约220MB小文件64KB分块循环读约430ms约1MB大文件QTextStream按行读约520ms约2MB文本处理从数据能看到readAll()在速度上并没有明显优势因为现代操作系统的大块顺序读取性能非常接近。分块读在内存上优势巨大却几乎没有性能损失。所以结论很直接大文件无脑分块读。写入方面小批量多次write()性能很差因为每次write()都可能触发系统调用。把数据拼接到一个QByteArray再一次性写入速度能快一个数量级。5.2 文件被占用与被删除的恢复策略这是Windows上绕不开的问题文件正在被另一个程序打开你的open(WriteOnly)会失败。而Linux下不存在这种文件锁你能成功打开但写入后数据是否真的落盘又是另一回事。排查这类问题的标准流程检查open()返回值失败立刻用errorString()看原因用isWritable()先判断文件是否可写区分“文件不存在”和“权限不足”两种情况给用户不同的提示如果只是短暂占用加上重试机制bool writeFileWithRetry(const QString path, const QByteArray data, int maxRetries 3) { for (int i 0; i maxRetries; i) { QSaveFile file(path); if (file.open(QIODevice::WriteOnly)) { file.write(data); return file.commit(); } qWarning() 尝试 i 1 失败: file.errorString(); QThread::msleep(200 * (i 1)); // 退避 } return false; }5.3 跨平台文件路径的坑Windows路径分隔符是\Unix是/。Qt内部统一使用/作为路径分隔符在构造路径时推荐直接用/拼接QString path QDir::currentPath() /data/config.ini;而下面这种硬编码\\的方式在Unix上会失效QString badPath QDir::currentPath() \\data\\config.ini;另外有一个QDir::separator()它返回当前系统的路径分隔符。但那是在拼接显示路径时用的传给Qt的文件路径API反而统一用/更稳。中文路径问题也经常磕绊。Qt的QString内部是UTF-16传入中文路径本身没问题。真正的问题是如果一个路径字符串是从GBK编码的字节流转换过来的就必须先正确转换成UTF-16再去构造QFile否则文件根本打不开。5.4 大小写敏感问题文件系统之间的差异也是新手重灾区。Windows的文件名不分大小写Linux区分macOS默认不区分但可以配置区分。如果你在Windows上开发时用了Config.ini放到Linux服务器上一个用config.ini访问就找不到文件。一个稳妥的做法是所有文件名统一小写别跟文件系统较劲。5.5 编码导致的写入内容错乱写入用错编码最典型的情况是Qt 6默认QString转QByteArray用UTF-8而某个旧程序用GBK解析结果中文变成菱形乱码。解决思路就是前面说到的用QTextStream::setEncoding显式指定编码不要依赖隐式转换。这里再提一个容易被忽略的点默认构造函数创建的QByteArray是空的和QString()交互时toUtf8()得到的字节数是0。但QString().toLocal8Bit()可能有一个字节根据系统编码或者0字节这在拼接写入内容时可能会产生意外。5.6 测试与模拟文件句柄的状态pos()方法返回当前读写位置这个跟文件句柄的游标概念一致。写代码时想判断一个文件是否可读可写isReadable()、isWritable()返回的是“打开模式里是否有读/写标志”而不是“文件系统上的实际权限”。这两个概念经常被混淆。我见过这样一个bug程序用QFile::exists()判断文件是否存在存在才去open但两个调用之间文件被别人删了open失败程序崩了。正确做法是直接open然后判断返回值不要先exists再open。6. 常见问题与排查技巧速查表整理了几条实战中高频出现的问题按“现象-原因-解法”的方式速查。现象常见原因解决思路open失败errorString提示Permission denied文件被其他进程独占打开或权限不足检查占用程序提升权限改用只读方式先探测写入后文件内容为空使用了WriteOnly但没加Truncate旧内容可能还在或者写入位置在文件开头导致覆盖确认加Truncate写完调用close或flush读出来中文乱码编码不匹配用QTextStream显式指定编码查看文件是否带BOM行读取时最后一行不处理atEnd()在最后一行没有换行符时提前返回true改用while (file.readLine())或自己计数行数Windows上rename失败目标文件存在且被占用先remove再rename或者用QSaveFile程序崩溃后配置文件损坏直接原地写没做原子写入换用QSaveFile或临时文件rename方案大文件readAll内存爆掉一次性读入内存分块读或按行读设置大小上限写入大量小片段性能极低频繁write触发系统调用拼接成QByteArray后一次性写入还有两个常见的误用需要专门说第一个QFile::copy()和QFile::rename()的区别。copy()是复制内容原文件保留rename()是移动文件同一文件系统内。用rename()实现“移动文件”在跨文件系统时可能失败因为底层可能是copydelete。另一个细节是copy()在目标文件已存在时返回false需要在调用前先remove目标文件但这又引出一个竞态窗口。第二个readLine()拿到的结果包含换行符。处理时需要自己chop()或者trimmed()。别以为Qt会自动帮你把换行符去掉这是初学者最常见的问题之一。7. 实操心得与个人建议这篇内容写到这里核心的东西都过了一遍。最后想分享一个我从实际项目里总结出来的经验写文件操作代码时永远不要信任“正常流程”。所谓正常流程就是假设文件一定存在、权限一定够、磁盘一定有空间、文件名一定合法。现实是这四条每一条都可能出幺蛾子。所以我写QFile代码的最低底线是每次open()之后立刻判断返回值失败就打印errorString()并给用户可操作的提示而不是闷头往下跑。在这个基础上能用QSaveFile的地方不用QFile写能分块的不一次性读完能用QTextStream显式指定编码的绝不依赖隐式默认。还有一条很实在的建议给你的文件操作代码写单元测试。不需要覆盖所有操作系统分支但至少覆盖“文件不存在”“文件为空”“文件被占用”三个场景。文件操作看似基础却是程序崩溃率最高的区域之一。把这三个场景测稳了能帮你挡掉一多半线上翻车事故。另一个实操里特别好用的小技巧是如果你需要调试文件内容可以用qDebug() file.readAll().left(64);快速看文件头部字节配合十六进制视图判断编码类型和文件格式。这个小技巧在排查编码乱码和二进制格式解析问题时特别高效。

相关新闻

公用桌面防数据泄露:从屏幕保护到锁定连接的完整加固方案

公用桌面防数据泄露:从屏幕保护到锁定连接的完整加固方案

公用桌面上的数据泄露,往往不是被外部黑客“攻”出来的,而是被人“顺便看”出来的。你随便在办公室或公共区域的共享电脑上看一眼,可能会发现上一个人走的时候,网盘还开着、邮箱还没退出、微信静默挂在后台,甚至连 Exc…

2026/10/20 10:50:16 阅读更多 →
5777张垃圾检测数据集:六场景落地解析与训练调参实践

5777张垃圾检测数据集:六场景落地解析与训练调参实践

先说说我是怎么接触到这套数据的。有朋友丢给我一份垃圾检测数据集,文件夹里整整齐齐放了5777张图片,标题却一口气列了智慧城市环卫管理、自动化清洁机器人、环境监测与评估、违规倾倒监控、垃圾分类辅助系统、无人机环境巡检六七个应用方向。我当时的第…

2026/10/19 8:28:11 阅读更多 →
Pico一体机Unity工程从零到可运行APK的完整指南

Pico一体机Unity工程从零到可运行APK的完整指南

简介:面向Pico一体机开发者的Unity工程文件包,基于Unity 5.6.1f1搭建,适合准备入手VR一体机开发、希望减少初始配置成本的团队或个人。包内共1632个文件,除C#脚本、DLL库、Prefab预制体、Shader、Unity场景、FBX模型、PNG贴图等直…

2026/10/20 10:06:31 阅读更多 →

最新新闻

OpenProject 上手指南:免费开源自托管项目管理

OpenProject 上手指南:免费开源自托管项目管理

OpenProject 上手指南:免费开源自托管项目管理 【免费下载链接】openproject OpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue trac…

2026/10/20 10:53:45 阅读更多 →
Android 安全校验下沉到原生层:防 patch 与构建期自动化

Android 安全校验下沉到原生层:防 patch 与构建期自动化

把判断写进机器码,再把指纹维护交给构建流程,让 patch 无利可图。前言 签名校验落地后,很多团队会松一口气:重打包必然重签名,重签名必然改指纹,运行时比对一下就能发现。逻辑没错,问题出在校验…

2026/10/20 10:53:45 阅读更多 →
三步装好 meta-overlayfs 元模块:让 KernelSU 模块真正改到 /system

三步装好 meta-overlayfs 元模块:让 KernelSU 模块真正改到 /system

三步装好 meta-overlayfs 元模块:让 KernelSU 模块真正改到 /system 【免费下载链接】KernelSU A Kernel based root solution for Android 项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU KernelSU 模块对 /system 的修改,要靠元模…

2026/10/20 10:53:45 阅读更多 →
LSTM与Transformer时间序列预测实战对比:源码解析与调参避坑指南

LSTM与Transformer时间序列预测实战对比:源码解析与调参避坑指南

简介:面向时间序列预测任务的LSTMTransformer混合模型PyTorch实现,适合需要多特征输入、单变量输出场景的研究者与开发者;可直接迁移到风电、光伏、寿命预测、浓度预测等项目中,也适合作为学习Transformer与LSTM结合的入门范例。压…

2026/10/20 10:53:45 阅读更多 →
如何快速部署EspoCRM开源CRM:从零到能跑生产业务

如何快速部署EspoCRM开源CRM:从零到能跑生产业务

如何快速部署EspoCRM开源CRM:从零到能跑生产业务 【免费下载链接】espocrm EspoCRM – Open Source CRM Application 项目地址: https://gitcode.com/GitHub_Trending/es/espocrm EspoCRM是一款免费开源的客户关系管理系统(CRM)&#…

2026/10/20 10:53:45 阅读更多 →
防误删+高效查单双buff加持!快递批量查询高手轻松搞定物流管理

防误删+高效查单双buff加持!快递批量查询高手轻松搞定物流管理

电商大促过后,面对成百上千条快递单号,手动逐单查询不仅耗时费力,稍不注意手滑点错清空表格,辛苦整理的全部物流数据就会瞬间丢失,后续对账、售后跟进全乱套。今天就给大家带来一套兼顾效率与数据安全的保姆级教程&…

2026/10/20 10:52:44 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →