Flutter读取assets压缩文件报错:FileSystemException文件不存在
解决Flutter中Assets压缩包找不到的问题
错误原因
你直接用File('assets/res.zip')访问资源文件是错误的——Flutter的Assets打包后并非以普通文件系统路径存在,APP运行时无法通过本地文件路径直接访问,因此会抛出No such file or directory错误。
解决方案步骤
1. 修正资源加载方式
必须使用Flutter提供的rootBundle来加载Assets资源,而不是File类。同时需要处理异步操作(rootBundle.load是异步方法)。
2. 使用合法的可写目录
直接写入out/相对路径会因权限或路径无效失败,需用path_provider包获取APP沙盒内的可写目录。
完整修改代码
首先,在pubspec.yaml中添加path_provider依赖:
dependencies: flutter: sdk: flutter archive: ^3.3.7 # 替换为最新版本 path_provider: ^2.1.1 # 替换为最新版本
然后修改提取逻辑:
import 'package:flutter/services.dart'; import 'package:archive/archive.dart'; import 'dart:io'; import 'dart:typed_data'; import 'package:path_provider/path_provider.dart'; Future<void> extractZip() async { // 1. 从Assets加载压缩包 final ByteData assetData = await rootBundle.load('assets/res.zip'); final Uint8List bytes = assetData.buffer.asUint8List(); // 2. 解码Zip文件 final Archive archive = ZipDecoder().decodeBytes(bytes, verify: true, password: '123'); // 3. 获取APP可写的文档目录 final Directory appDocDir = await getApplicationDocumentsDirectory(); final String outDirPath = '${appDocDir.path}/out'; // 4. 提取文件到目标目录 for (final ArchiveFile file in archive) { final String targetPath = '$outDirPath/${file.name}'; if (file.isFile) { final List<int> fileContent = file.content as List<int>; File(targetPath) ..createSync(recursive: true) ..writeAsBytesSync(fileContent); } else { Directory(targetPath).createSync(recursive: true); } } } // 调用示例(比如在initState中) @override void initState() { super.initState(); extractZip().catchError((error) => print('提取失败: $error')); }
关键注意事项
- Assets配置检查:确保
pubspec.yaml中assets配置缩进正确(需位于flutter节点下),否则资源不会被打包:flutter: assets: - assets/res.zip - 异步处理:
rootBundle.load和getApplicationDocumentsDirectory都是异步操作,必须用await处理,不能同步调用。 - 权限问题:不要尝试写入APP沙盒以外的目录,否则会触发权限错误。
内容的提问来源于stack exchange,提问作者Qqq
相关产品推荐
相关产品推荐

