必须通过p/invoke调用leveldb.dll或使用leveldb.net等封装库操作leveldb文件,litedb不兼容leveldb格式;新项目推荐rocksdb.sharp;需注意dll路径、平台匹配、绝对路径、资源释放及wal可靠性。

LevelDB 本身没有官方 C# 绑定,直接在 C# 里“操作 LevelDB 文件”必须通过 P/Invoke 调用原生 leveldb.dll,或依赖成熟封装库——否则会遇到文件锁、内存泄漏、崩溃等不可控问题。
用 LevelDB.Net 还是 LiteDB?别被名字骗了
LevelDB.Net 是较早的 P/Invoke 封装,但长期未维护(最新版仍基于 LevelDB 1.20),Open 时若路径含中文或空格容易抛 System.AccessViolationException;而 LiteDB 虽常被误认为 LevelDB 替代,实为纯 C# 实现的 BSON 文档库,不兼容 LevelDB 文件格式,也不能读写 .ldb 文件。
- 要读写已有 LevelDB 数据目录(比如从 Go/Python 服务导出的),必须用
LevelDB.Net或自己封装leveldb原生调用 - 新项目想用嵌入式键值存储,优先考虑
RocksDB.Sharp(RocksDB 的 C# 封装,LevelDB 衍生,API 兼容性好,持续更新) -
LevelDB.Net的WriteOptions默认禁用同步,断电可能丢最后几条写入,生产环境务必设Sync = true
LevelDB.Net 打开数据库失败的三个常见原因
错误信息如 Unable to load DLL 'leveldb.dll' 或 Invalid argument: ... does not exist (create_if_missing is false),基本都卡在这三处:
- 没把
leveldb.dll(Windows)或libleveldb.so(Linux)放进输出目录,且没配PATH或LD_LIBRARY_PATH - 目标平台不匹配:x64 程序加载了 x86 的
leveldb.dll,或 .NET 6+ 用的Microsoft.NETCore.App.Host机制导致原生库加载路径异常 - 路径传的是相对路径(如
"./data"),但当前工作目录不是你预期的——建议用绝对路径:Path.GetFullPath("data")
写入和读取时必须注意的生命周期管理
LevelDB.Net 的 DB、WriteBatch、Iterator 都包装了非托管资源,不显式 Dispose() 会导致句柄泄漏,多次打开同一路径还可能触发 Windows 文件独占锁报错 IO exception: data/000003.log: Permission denied。
- 用
using包裹所有可释放对象:using var db = DB.Open(...),别只对DB用,Iterator同样要 -
WriteBatch不是线程安全的,多线程写入必须每个线程新建实例,或加锁 - 迭代器
Iterator在db.Dispose()后立即失效,不能跨作用域保存引用
LevelDB 文件结构(MANIFEST、LOG、*.ldb)对程序关闭非常敏感,强制杀进程后下次打开大概率报 Corruption: ... unexpected end of file。真要保证可靠性,要么用 RocksDB.Sharp 开启 WalDir 和 ManualWalFlush,要么接受它本来就是为“单机、可控、低频写入”场景设计的——这点容易被忽略。










