Flutter调用readJson函数报错 无法加载JSON资源打印列表
问题根因
rootBundle.loadString() 仅支持加载提前在pubspec.yaml中声明、打包进APP安装包的静态资源,无法读取应用运行时生成、存储在设备本地应用沙盒目录下的文件。
你写入文件时用的是getApplicationDocumentsDirectory()返回的应用私有文档目录,这个路径下的文件不属于rootBundle的加载范围,所以哪怕文件真实存在,调用rootBundle加载也会抛出资源不存在的异常。
另外你贴的readJson代码本身还有几个逻辑bug,就算路径修对了也会运行报错:
- 循环终止条件写的是
i <= myInts.length,列表下标从0开始,最后一次循环会触发下标越界异常 - 循环内只打印了下标i,没有打印列表元素,不符合你最初“打印列表元素”的预期
- 你的saveToJsonFile方法直接把传入的List
修复步骤
- 替换文件读取逻辑,放弃rootBundle,使用dart:io的File类读取本地沙盒文件,路径拼接规则和写入时保持完全一致。
修正后的readJson代码如下:
import 'dart:io'; import 'dart:convert'; import 'package:path_provider/path_provider.dart'; Future<void> readJson() async { // 获取和写入逻辑一致的应用文档目录 final Directory appDocDir = await getApplicationDocumentsDirectory(); final String targetPath = '${appDocDir.path}/contents.json'; // 直接读取本地文件内容 final String response = await File(targetPath).readAsString(); final data = json.decode(response); // 注意:这里要确保你写入的JSON结构里存在content_entries字段,值为数字数组 final myInts = (data['content_entries'] as List).cast<double>(); // 修正循环条件,打印实际的列表元素 for(int i = 0; i < myInts.length; ++i){ print(myInts[i]); } }
- 对齐读写两端的JSON结构:如果你写入时直接传入的是内容列表,需要把写入逻辑调整为包裹content_entries字段的结构,示例:
Future<File> saveToJsonFile(List<double> contentEntries, String filename) async { // 组装和读取逻辑匹配的JSON结构 final Map<String, dynamic> saveData = { 'content_entries': contentEntries }; final String encodedData = jsonEncode(saveData); final Directory appDocDir = await getApplicationDocumentsDirectory(); final String appDocPath = '${appDocDir.path}/$filename'; return File(appDocPath).writeAsString(encodedData); }
补充说明
只有当你需要读取预置在项目里、和APP一起打包安装的只读资源时,才需要用
rootBundle.loadString()。这种场景下你需要把资源文件放在项目的assets目录下,并且在pubspec.yaml的flutter -> assets字段下声明对应文件路径。注意这种静态资源是只读的,你运行时写入到应用文档目录的内容不会修改这个打包好的静态资源,二者是完全独立的两个文件。
内容的提问来源于stack exchange,提问作者mchd
相关产品推荐
相关产品推荐

