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
相关产品推荐
相关产品推荐

