You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:10:59