如何将SQLite数据库或对应List<T>保存至本地设备实现应用重启后数据恢复
你当前代码中使用的SQLiteAsyncConnection,本质是直接对接你指定路径下的本地sqlite文件做读写操作——也就是说只要你不对文件做手动删除、不对应用做清除数据操作,数据库本身就是持久化的,应用重启后可以直接读取,根本不需要额外把查询出来的List集合手动写入文件。
很多刚接触SQLite-net的开发者会误以为内存里的表是临时数据,实际上你执行的
CreateTableAsync、后续的增删改操作,都会直接落盘到LocalApplicationData目录下的LocalDb.sqlite文件;ToListAsync()只是把磁盘上的表数据加载到内存做临时运算,不存在“查询出来就丢失”的问题。
方案1:原生效持久化(零额外开发量,最推荐)
你现在的代码只完成了数据库初始化和数据查询,只要补全数据写入的逻辑,不需要手动调用File方法,所有数据会自动持久化:
- 新增单条日记:直接调用
await conn.InsertAsync(你的HumorDiary实例),操作完成后数据自动写入磁盘文件 - 批量写入整个集合:调用
await conn.InsertAllAsync(PagineDiario)即可完成批量落盘 - 应用重启后,重新执行你原本的连接、建表、查询逻辑,即可完整恢复所有历史数据
注意:不要把数据库路径设在临时缓存目录(比如
Path.GetTempPath()),这类目录的文件会被系统自动清理,无法实现持久化。
方案2:单独持久化List集合为独立本地文件
如果你确实需要绕过原sqlite文件,把内存中的PagineDiario集合单独存为本地文件,需要先解决自定义对象无法直接被File方法写入的问题——File.Write类的方法仅支持写入字符串、字节数组两类内容,必须先经过序列化转换:
- 轻量文本存储方案:用System.Text.Json把集合序列化为JSON字符串后写入文件
读取时只需反向操作:读取文件内容为字符串,再通过// 集合序列化为JSON字符串 string jsonContent = JsonSerializer.Serialize(PagineDiario); // 定义持久化文件路径 string savePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "diary_backup.json"); // 异步写入文件 await File.WriteAllTextAsync(savePath, jsonContent);JsonSerializer.Deserialize<List<HumorDiary>>即可还原集合。 - 高密度二进制存储方案:用MemoryPack、Protobuf等序列化工具把集合转为字节数组,再通过
File.WriteAllBytesAsync写入文件,相比文本方案占用空间更小、读写速度更快。
方案3:备份整个SQLite数据库文件
如果你需要完整迁移/备份整个数据库,不需要逐行重新写入表数据,直接复制源sqlite文件即可:
// 先等待所有正在执行的数据库操作完成,避免文件被系统占用锁定 await conn.CloseAsync(); // 定义备份文件路径 string backupPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "LocalDb_backup.sqlite"); // 复制原数据库文件到备份路径 File.Copy(LocalDB, backupPath, overwrite: true);
注意:执行文件复制操作时,必须确保没有正在进行的数据库读写,否则会因为文件被占用导致复制失败。
之前File.Write操作失效的原因
你之前直接把List<HumorDiary>对象传入File.Write方法时,方法无法将自定义类型自动转换为字符串或字节数组——如果没有显式做对象序列化步骤,写出去的内容只是对象在内存中的类型描述,根本无法读取恢复,自然达不到持久化效果。
内容的提问来源于stack exchange,提问作者signalover

