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

Flutter从Google Drive下载SQLite数据库时遇加密/非数据库错误求助

解决Flutter中Google Drive下载SQLite数据库后提示“不是数据库或已加密”的问题

问题根源

直接使用Google Drive公开共享链接下载时,返回的是网页预览内容而非实际数据库文件,导致替换后的文件无法被SQLite识别,触发file is encrypted or is not a database错误。

解决方案

1. 修正Google Drive直接下载链接

Google Drive的普通共享链接是预览页面地址,需要转换为直接下载链接:将原链接中的/file/d/[文件ID]/结构替换为/uc?export=download&id=[文件ID]。
你的链接修改后应为:

String databaseUrl='https://drive.google.com/uc?export=download&id=1Qt4xigUU3d7tO-sdyZVZyQKei9l6AvBz';

2. 增加文件有效性校验

下载完成后,先验证文件是否为合法的SQLite数据库(通过检查文件头特征),避免无效文件覆盖原数据库:

bool isValidSqliteFile(File file) {
  try {
    final header = file.readAsBytesSync().sublist(0, 16);
    return String.fromCharCodes(header) == 'SQLite format 3';
  } catch (_) {
    return false;
  }
}

3. 优化数据库替换流程

先下载到临时文件,验证通过后再替换原数据库,防止替换失败导致原数据库损坏。

修改后的完整代码

import 'dart:io';
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

Future<void> checkAndReplaceDatabase() async {
  // 修正为Google Drive直接下载链接
  String databaseUrl='https://drive.google.com/uc?export=download&id=1Qt4xigUU3d7tO-sdyZVZyQKei9l6AvBz';
  final int expectedVersion = 2;

  String databasesPath = await getDatabasesPath();
  String path = join(databasesPath, 'contacts.db');
  String tempPath = join(databasesPath, 'temp_contacts.db');

  Database? database;
  try {
    // 尝试打开现有数据库
    database = await openDatabase(path);
    int currentVersion = await database.getVersion();

    if (currentVersion < expectedVersion) {
      await database.close();

      var response = await http.get(Uri.parse(databaseUrl));
      if (response.statusCode == 200) {
        // 先写入临时文件
        File tempFile = File(tempPath);
        await tempFile.writeAsBytes(response.bodyBytes);

        // 验证临时文件是否为合法SQLite数据库
        if (isValidSqliteFile(tempFile)) {
          // 删除原数据库,替换为临时文件
          await File(path).delete();
          await tempFile.rename(path);

          // 打开新数据库并设置版本
          Database newDatabase = await openDatabase(path);
          await newDatabase.setVersion(expectedVersion);
          await newDatabase.close();

          print('Database updated to version $expectedVersion.');
        } else {
          print('Downloaded file is not a valid SQLite database.');
          await tempFile.delete();
        }
      } else {
        print('Failed to download the new database. Status code: ${response.statusCode}');
      }
    } else {
      print('Database is already up to date (version $currentVersion).');
    }
  } catch (e) {
    print('Error during database check: $e');
    if (database != null) {
      await database.close();
    }
  }
}

bool isValidSqliteFile(File file) {
  try {
    final Uint8List header = file.readAsBytesSync().sublist(0, 16);
    return String.fromCharCodes(header) == 'SQLite format 3';
  } catch (_) {
    return false;
  }
}

内容的提问来源于stack exchange,提问作者PLAA Hemantha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:52:44