Flutter使用sqflite打开SQLite数据库时Android端文件大小变化问题
Android端SQLite数据库打开后大小变化的原因
核心原因:Android系统SQLite的默认行为差异
- 文件大小页对齐:你看到的大小差值(30240768-30236672=4096字节)刚好是SQLite默认的4KB页大小。Android系统自带的SQLite库在打开数据库时,会自动将文件大小调整为页大小的整数倍——如果下载的数据库文件大小不符合这个要求,就会在文件末尾补空字节,直接导致主数据库文件变大。而iOS的SQLite实现没有这个强制对齐的默认逻辑。
- WAL日志模式默认启用:Android默认使用
WAL(写前日志)模式,打开数据库时除了调整主文件大小,还会自动生成xxx.db-wal和xxx.db-shm两个辅助文件(虽然你看到的是主文件变大,但WAL的初始化逻辑也可能触发主文件的预分配操作)。iOS默认使用DELETE日志模式,不会触发这类预分配行为。
为什么校验和会失效
打开数据库后,主文件已经被SQLite修改(补全空字节、预分配空间),文件内容和下载的原始文件不一致,自然导致校验和不匹配。后续添加数据时,WAL模式下SQLite会优先写入日志文件,定期将日志合并到主数据库,且主数据库只会标记空闲页不会自动收缩,所以文件会持续增长。
解决方向
- 校验和验证必须在打开数据库之前执行,打开后文件已被修改,无法用原始校验值验证。
- 如果需要保持打开后的文件与原始文件校验一致,可以在打开数据库时显式指定
journal_mode=DELETE禁用WAL:Database database = await openDatabase( "${appDocumentsDir.path}/$dbFileName", onConfigure: (db) async { await db.execute("PRAGMA journal_mode=DELETE;"); }, ); - 或者提前将下载的数据库文件手动调整为页大小的整数倍,避免SQLite自动修改。
内容的提问来源于stack exchange,提问作者Jungwon
相关产品推荐
相关产品推荐

