news 2025/12/23 10:46:07

从零开始:如何用 C# 开发一款媲美 “AnyTxt” 的文件内容搜索工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零开始:如何用 C# 开发一款媲美 “AnyTxt” 的文件内容搜索工具

起文件内容搜索工具,那么不得不提到“AnyTxt”,号称本地知识库检索的终极答案。唯一的不足可能就是索引更新机制,不能实时监视文件更改从而更新索引,最小定期更新间隔为半小时,容易导致cpu占用率高,毕竟是全盘全文件类型索引。

很多时候,其实我们对文件内容的搜索,是一个简单文档管理需求,我们期望能的是快速定位文件,而不仅仅是信息。这时候对文件夹以及文件类型的限制就很重要了。还有就是有可能我们会对比如CAD图纸(.dwg、.dxf)的图签或者文件数据库(.db)的表名等特殊文件格式的自定义内容感兴趣。这时候就需要自己来实现扩展了。再加上很多时候,磁盘的信息都是敏感数据,一定要保证软件程序的安全。

因此,我们决定用C#开发一款开源的Windows平台全文搜索工具-TDSContent,并将整个开发过程中的思路与遇到的“坑”记录下来。最终代码与实现已完全开源。https://github.com/LdotJdot/TDSContent

TDSContent_Intro

我们接下来将对标AnyTxt的核心功能来TDSContent的技术实现。

二、从对标AnyTxt特性来设计TDSContent技术实现

在网上搜集了AnyTxt的特性与技术优势后,对应地对TDSContent在各个环节的实现进行了分析。具体如下:

image

2.1 对标AnyTxt(速度): 1 秒内出结果,自建索引,检索延迟 < 100 ms

文件全文关键词检索的方式大致分两种:

直接检索,先枚举出候选文件,在文件中查询出结果,返回对应文件信息。

索引检索,在索引中匹配关键词,生成索引匹配结果,返回索引匹配结果对应的文件信息。

直接检索适合于纯文本类的高效搜索,此时信息的读取成本低,即从文件中读取文本与转化速度都快。比较有代表性的就是ripgrep这类工具,直接开多个线程快速扫描所有;

索引检索适合信息量较大、信息的读取成本较高的场景,例如文件读取速度较慢或读取后存在较耗时文本解析过程。此时就需要提取解析文件,将文本索引存储好,提高后续搜索速度。比较有代表性的就是ElasticSearch这类工具。

为了更好支持更多类型文件内容搜索,TDSContent选择的是索引检索这种模式,采用了与ElasticSearch同样的Lucene的.net移植版本Lucene.net作为索引架构。该架构提供了完整的查询引擎和索引引擎,内部通过倒排索引查询,速度响应非常快。对于每个目标文件夹,我们都将单独进行索引创建维护,这样在近实时的更新写入与读取时都有非常好的性能。

现使用是Lucene.Net.Analysis.SmartCn(4.8.0-beta00017,要勾选预览版本才能在Nuget中搜得到),自带了支持中文分词的Analyzer。

2.2 对标AnyTxt(格式):100+ 文档类型,包括 Office/WPS/PDF/EPUB/MOBI/CHM/HTML/TXT/代码/思维导图等

文件内容的检索主要对象就是文本。对文档格式的支持无非就是将文件转换为我们感兴趣的文本信息部分。对于纯文本文件可以直接读取即可,如果是其他类型则需要进行解析转换。

TDSContent默认内置的转换器用开源库实现了几种常用格式的解析:

PDF: 选择PDFiumCore(Apache-2.0 license),它是对PDFium(BSD-3-Clause license)的封装,可从Nuget直接拉取,提供了.NET的接口,可以直接提取出可读的string文本无需额外转换。其他试过的还有貌似效果更好的iTextSharp,但他的协议AGPL v3,怕有风险。

docx,pptx: 用Open-XML-SDK(MIT),Nuget直接拉取简单易用。

dwg: 用ACadSharp(MIT)。现在dwg的解析库已经相对成熟了(遥想几年前dwg的解析还是个难题,还得用Teigha转dxf后再处理)。

dxf: 用netDxf(MIT),可从Nuget直接拉取。ACadSharp也能解析dxf,但实测下来部分dxf会报错,而netDxf兼容性更好。

doc,ppt: 20251018新增,用mit开源库实现二进制文件的文本读取(https://github.com/mayswind/SimpleOfficeReader)

纯文本: 直接用C#代码读取,包括txt,md,json,log,ini等。

大家可以通过实现项目中的IFileToStringConverter接口,实现自己的格式解析器。

public interface IFileToStringConverter : IDisposable

{

string Extension { get; }

string Convert(string filepath);

}

2.3 对标AnyTxt(OCR):图片 & 扫描件可搜,支持 JPG/PNG/扫描 PDF,内嵌 CPU/GPU 双引擎

TDSContent中对于图片OCR解析转换暂无相关计划,有需要的话可以自己实现。可以考虑使用Tesseract实现本地图片的解析。

2.4 对标AnyTxt(搜索语法):支持精准 / 模糊 / 正则,AND/OR/NOT、通配符、二次结果内筛选

由于基于的是Lucene索引框架,因此TDSContent能支持Lucene的所有查询方式,主要包括:

查询方式 意义

TermQuery 精确查询

TermRangeQuery 查询一个范围

PrefixQuery 前缀匹配查询

WildcardQuery 通配符查询

BooleanQuery 多条件查询

PhraseQuery 短语查询

FuzzyQuery 模糊查询

TDSContent默认的是采用”短语查询“,其他查询方式未UI中还未开放,但内部基本已实现。

2.5 对标AnyTxt(预览):右侧浮窗高亮关键词,无需打开源文件即可复制文本、翻译、跳转目录

尽管我们在Lucene引擎中,对每个文件的文本内容是通过索引的方式执行了全文存入的。但是我们没有做预览窗口。为了简洁,仅在目标结果文件下方做了最多5行的高亮匹配文本展示。

results

其他如翻译功能也没实现。

2.6 对标AnyTxt(索引策略):实时监控 + SSD 优化,自动增量更新,AES-256 加密缓存,支持网络共享盘

TDSContent没有实时监控线程。因此文件的更新是通过索引项目的USN日志实现。基于USN的好处是,哪怕用户在程序关闭状态下执行内容修改、重命名、文件夹修改、路径移动等操作,当下一次程序启动时,会依照记录自动实现对应索引结构更新。这样会非常经济且高效,不会有严重的卡顿以及频繁扫盘等问题,尤其不影响笔记本续航,缺点就是必须依赖USN。

2.7 对标AnyTxt(扩展性)

本项目为开源免费软件,可任意扩展。

三、其他

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/19 5:08:24

Java: FATAL ERROR: processing of -javaagent failed

在使用 Java 程序时&#xff0c;遇到 FATAL ERROR: processing of -javaagent failed 这样的错误通常意味着在尝试使用 -javaagent 参数来加载一个 Java Agent 时发生了问题。-javaagent 参数用于在 JVM 启动时加载一个 Java Agent&#xff0c;这种 Agent 可以用来监视、诊断或…

作者头像 李华
网站建设 2025/12/12 11:54:29

1小时快速原型:用JTAG实现设备诊断工具

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速开发一个JTAG设备诊断工具原型&#xff0c;要求&#xff1a;1.自动检测JTAG链设备 2.读取关键寄存器值 3.基本故障诊断 4.简洁的GUI界面 5.支持结果导出。使用PythonQT框架&…

作者头像 李华
网站建设 2025/12/12 11:53:11

Mac用户必备:5个高效SSH工具对比与实战技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个SSH工具对比网页&#xff0c;要求&#xff1a;1. 对比Termius、iTerm2、Royal TSX、SecureCRT和原生终端&#xff1b;2. 包含功能对比表格&#xff1b;3. 每种工具的特色功…

作者头像 李华
网站建设 2025/12/12 11:53:11

如何用AI快速生成JTAG调试工具代码

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请生成一个基于Python的JTAG调试工具代码框架&#xff0c;要求包含以下功能&#xff1a;1.支持基本的TAP控制器状态机实现 2.提供简单的JTAG指令发送接口 3.包含TCK/TMS/TDI/TDO信号…

作者头像 李华
网站建设 2025/12/12 11:53:08

Vue3 defineOptions实战:构建可配置表单组件

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个可配置的表单组件FormBuilder&#xff0c;使用defineOptions定义&#xff1a;1. props接收fields数组配置表单字段&#xff1b;2. emits提交事件&#xff1b;3. 计算属性动…

作者头像 李华
网站建设 2025/12/12 11:52:07

ReadCat免费开源小说阅读器:5分钟快速上手完整指南

ReadCat免费开源小说阅读器&#xff1a;5分钟快速上手完整指南 【免费下载链接】read-cat 一款免费、开源、简洁、纯净、无广告的小说阅读器 项目地址: https://gitcode.com/gh_mirrors/re/read-cat ReadCat是一款完全免费、开源纯净的小说阅读器&#xff0c;致力于为用…

作者头像 李华