优先用 microsoft.visualbasic.fileio.textfieldparser 解析 csv,它正确处理引号、换行、空字段;json 大文件查询应使用 jsondocument.parse 而非 jsonconvert.deserializeobject;csv/json 响应超 200ms 或需多表/分页/并发写时,应迁移到 sqlite。

CSV 文件读取:用 File.ReadAllLines 最快但不安全
直接用 File.ReadAllLines 读 CSV 看似简单,实际会崩在带换行符的字段(比如 Excel 导出的备注列里有回车)、中文乱码、逗号嵌套等场景。它只是按行切,完全不管 CSV 的 RFC 4180 规则。
实操建议:
- 优先用
Microsoft.Data.SqlClient不合适——那是 SQL Server;这里该用System.Data.Common+Microsoft.Data.DataView?不对,太重。轻量级选Microsoft.VisualBasic.FileIO.TextFieldParser(别被命名劝退,C# 项目可直接引用Microsoft.VisualBasicNuGet 包,稳定且处理引号/换行/空字段都正确) - 如果必须手写解析,至少用
StreamReader配合状态机,而不是Split(','))—— 后者在"a,b",c,"d,e,f"这种数据上直接错三列 - 编码问题高频:Windows 记事本存的 CSV 默认是
GBK或UTF-8 with BOM,File.ReadAllLines默认用UTF-8,BOM 会被当内容;显式传Encoding.UTF8或Encoding.Default更可控
JSON 文件查询:别用 JsonConvert.DeserializeObject 全量加载大文件
把几 MB 的 JSON 当“数据库”查,一上来就 JsonConvert.DeserializeObject<list>>(json)</list>,内存暴涨、GC 频繁,查一次卡两秒。这不是反模式,是典型误用。
实操建议:
- 小文件(System.Text.Json 的
JsonSerializer.Deserialize<t></t>没问题,类型安全又快 - 中大文件(>1MB)或只查部分字段:改用
JsonDocument.Parse+RootElement导航,它只解析 JSON 结构树,不 new 对象,内存占用低 60% 以上 - 想支持类似 SQL 的查询语法?别自己写解析器。用
System.Linq.Dynamic.Core库配合JsonElement转IEnumerable<object></object>,能写Where("Price > 100")这种字符串条件,但注意:字段名大小写要和 JSON 一致,price≠Price
文件即数据库的边界在哪:什么时候该换 SQLite
CSV/JSON 当数据库,本质是把磁盘 I/O 当查询引擎用。查一次开一次文件、全扫描、没索引、没事务——这些不是“功能缺失”,是设计定位决定的。
实操判断点:
- 单次查询响应超过 200ms(比如 10 万行 CSV 里
Where查某 ID)→ 该上SQLite - 需要多表关联、分页(
OFFSET/LIMIT)、模糊匹配(LIKE '%abc%')→ CSV/JSON 基本不可行 - 并发写入:两个进程同时
File.WriteAllText写同一个 JSON,大概率文件损坏;而SQLite的 WAL 模式天然支持多线程写 - 迁移成本极低:NuGet 装
Microsoft.Data.Sqlite,把原 CSV 用DbCommand批量 INSERT 进.db文件,后续代码只需改连接字符串和 SQL,业务逻辑几乎不动
查询性能陷阱:LINQ to Objects 不是 LINQ to SQL
很多人把 List<t></t> 从文件加载后,写 data.Where(x => x.Name.Contains("abc")) 就以为是“高效查询”。其实这是纯内存遍历,复杂度 O(n),且每次调用都重新扫描。
关键差异:
-
Where在内存集合上执行,无法跳过无关行;而 SQLite 的WHERE name LIKE ?可走索引(如果建了) - JSON 中用
JsonElement.GetProperty("name").GetString()做比较前,先确认字段存在(TryGetProperty),否则抛KeyNotFoundException,不是所有 JSON 行都有name - CSV 场景下,如果反复查同一列,别每次都
line.Split(',')[2]—— 先用TextFieldParser解析成对象列表,再用 LINQ,否则拆分开销比查询本身还高
文件当数据库,最易被忽略的是“查询意图”和“物理存储”的错配:你想要索引、缓存、并发控制,但文件系统只提供字节流。这点不认清,优化永远在边缘打转。










