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

Flutter Windows平台Sqflite_ffi数据库创建失败求助

Windows平台下Flutter加载Assets数据库的问题解决

你的代码在Android正常但Windows失效,核心问题在于未指定sqflite_ffi的数据库工厂类,以及Windows平台下资源加载的细节处理。以下是修正方案:

1. 确认pubspec.yaml的Assets配置

确保数据库文件已正确声明在pubspec.yaml中,路径要和代码里的一致:

flutter:
  assets:
    - assets/barcode-barcode.db

2. 修正数据库助手类代码

主要修改点:

  • 只初始化一次sqflite_ffi,避免重复执行
  • 打开数据库时必须指定databaseFactory: databaseFactoryFfi(Windows下默认sqflite实现不兼容)
  • 增加错误捕获,方便排查问题

修正后的完整代码:

import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:path_provider/path_provider.dart';

class DatabaseHelper {
  static final columnId = '_id';
  static final columnNome = 'nome';
  static final columnIdade = 'idade';

  // 单例模式
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  // 标记sqflite ffi是否已初始化
  static bool _ffiInitialized = false;

  Future<Database?> get database async {
    // 仅初始化一次sqflite ffi
    if (!_ffiInitialized) {
      sqfliteFfiInit();
      _ffiInitialized = true;
    }

    final databaseFactory = databaseFactoryFfi;
    final databasesPath = await getApplicationDocumentsDirectory();
    final path = join(databasesPath.path, "barcode.db");
    print("数据库路径: $path");

    final exists = await databaseExists(path);

    if (!exists) {
      print("从Assets复制新数据库");
      try {
        // 确保父目录存在
        await Directory(dirname(path)).create(recursive: true);
      } catch (e) {
        print("创建目录失败: $e");
        return null;
      }

      try {
        // 加载Assets中的数据库文件
        final ByteData data = await rootBundle.load("assets/barcode-barcode.db");
        final List<int> bytes = data.buffer.asUint8List(
          data.offsetInBytes,
          data.lengthInBytes,
        );
        // 写入文件并强制刷新
        await File(path).writeAsBytes(bytes, flush: true);
      } catch (e) {
        print("复制数据库文件失败: $e");
        return null;
      }
    } else {
      print("打开现有数据库");
    }

    // 必须指定databaseFactory为ffi工厂类,否则Windows下无法正常工作
    final db = await openDatabase(
      path,
      databaseFactory: databaseFactory,
    );
    return db;
  }
}

3. 排查步骤

如果仍然无法工作,按以下步骤排查:

  • 检查Assets文件路径:确认项目中assets/barcode-barcode.db确实存在,且pubspec.yaml中的路径和代码里的完全一致
  • 查看控制台输出:通过print的信息确认数据库路径是否正确,复制过程是否有错误
  • 检查文件权限:确保应用有权限读写getApplicationDocumentsDirectory()返回的路径(Windows下该路径默认有读写权限)

内容的提问来源于stack exchange,提问作者Thiago Carvalho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:15:07