Flutter中如何使用Directory访问assets下的子目录?
核心原因
dart:io 提供的 Directory 类仅能访问设备本地文件系统上的真实物理目录。你在项目中配置的 assets 资源在应用打包阶段会被编译进APK/IPA二进制安装包内部,不会以独立文件的形式解压到设备本地文件系统,因此直接传入assets/subdirectory/这类路径调用Directory必然报找不到目录的错误,调整前缀、斜杠的方案都不会生效,因为该路径从一开始就不在IO接口可访问的文件系统范围内。
你平时用rootBundle.loadString('assets/xxx/xxx')能正常读取文件,是因为Flutter的AssetBundle机制直接从安装包的二进制资源段读取内容,和本地文件系统的路径解析逻辑完全独立。
检索指定前缀资产文件的实现方案
不要尝试用IO接口直接访问assets目录,通过Flutter打包时自动生成的资产清单即可完成筛选:
- 第一步:确认所有需要检索的文件都已在
pubspec.yaml的assets字段下正确声明,支持直接声明子目录(即你当前用的assets/[子目录名]/格式),只要资源会被打进安装包即可。 - 第二步:运行时读取
AssetManifest.json(Flutter打包时自动生成的全量资产列表文件),从中筛选符合路径要求、文件名前缀匹配的资源。
代码实现
import 'package:flutter/services.dart' show rootBundle; import 'dart:convert'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; /// 检索指定assets子目录下,文件名以指定关键词开头的资源路径列表 /// [subDir] 目标子目录名,对应assets下的一级子目录 /// [keywordPrefix] 文件名匹配前缀 Future<List<String>> filterAssetsByPrefix(String subDir, String keywordPrefix) async { // 读取全量资产清单 final manifestContent = await rootBundle.loadString('AssetManifest.json'); final Map<String, dynamic> assetManifest = json.decode(manifestContent); final dirPathPrefix = 'assets/$subDir/'; // 筛选匹配项 return assetManifest.keys.where((assetPath) { // 过滤非目标目录下的资源 if (!assetPath.startsWith(dirPathPrefix)) return false; // 提取纯文件名(去除目录前缀) final fileName = assetPath.replaceFirst(dirPathPrefix, ''); // 匹配文件名前缀 return fileName.startsWith(keywordPrefix); }).toList(); } /// 如果业务需要用到IO可访问的真实文件路径,可以把资产写入临时目录后返回路径 Future<String> getAssetLocalPath(String assetPath) async { final byteData = await rootBundle.load(assetPath); final tempDir = await getTemporaryDirectory(); final fileName = assetPath.split('/').last; final targetFile = File('${tempDir.path}/$fileName'); await targetFile.writeAsBytes( byteData.buffer.asUint8List( byteData.offsetInBytes, byteData.lengthInBytes, ), ); return targetFile.path; }
调用示例
// 比如查找assets/subdirectory目录下,文件名以test开头的资源 final matchedAssetPaths = await filterAssetsByPrefix('subdirectory', 'test'); // 拿到路径后可直接通过rootBundle读取内容,或调用getAssetLocalPath转成本地IO路径使用
内容的提问来源于stack exchange,提问作者coco
相关产品推荐
相关产品推荐

