Flutter读取JSON文件抛出FormatException异常的问题排查
Flutter异步读取JSON文件报错排查与修复
问题原代码
void readJSON(String path) async { Directory appDocDir = await getApplicationDocumentsDirectory(); String appDocPath = appDocDir.path + '/' + path; print('Trying to read json file from ' + appDocPath); final Future<String> response = File(appDocPath).readAsString(); final data = await json.decode(response.toString()); final coordinates = await (data['elements'] as List).cast<double>(); for(int i = 0; i <= coordinates.length; ++i){ print(i); } }
运行时抛出两类异常:一类是FormatException,提示第1个字符位置存在意外字符,错误输出为Instance of 'Future<String>';另一类是类型不匹配异常,提示String类型无法作为int类型索引。
代码存在的具体错误
- 未等待文件读取异步任务完成:
File.readAsString()返回Future<String>类型,代码中没有加await等待结果返回,直接对Future实例调用toString()拿到的是固定字符串Instance of 'Future<String>',并非文件实际内容。将该字符串传入json.decode()时,由于内容不符合JSON格式,直接触发FormatException,和报错日志中第一个字符位置异常的描述完全匹配。 - 无意义的异步等待导致类型错误:
List.cast<double>()是内存中的同步类型转换操作,不存在异步逻辑,额外加await属于错误用法,会导致后续访问列表时触发类型匹配异常,对应日志中String无法作为int类型索引的报错。 - 循环边界设置错误:for循环终止条件写为
i <= coordinates.length,而Dart中List的合法索引范围是0到length - 1,当i等于length时会触发索引越界异常;且循环内仅打印索引值,没有打印对应元素内容,无法达到查看数据结构的目的。 - 异步函数返回值类型不规范:标记为
async的函数如果无返回值,应当声明返回类型为Future<void>,写为void会导致调用方无法正确等待异步任务执行完成,容易出现未捕获的异步异常。
修复后代码
import 'dart:convert'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; // 修正异步函数返回值类型 Future<void> readJSON(String path) async { Directory appDocDir = await getApplicationDocumentsDirectory(); // 使用字符串模板拼接路径,避免手动拼接分隔符出错 String appDocPath = '${appDocDir.path}/$path'; print('Trying to read json file from $appDocPath'); // 加await等待文件读取完成,拿到真实的文件内容字符串 final String fileContent = await File(appDocPath).readAsString(); // 传入真实文件内容解析JSON,json.decode本身是同步方法不需要额外await final data = json.decode(fileContent); // 去掉cast操作前多余的await,同步完成类型转换 final List<double> coordinates = (data['elements'] as List).cast<double>(); // 修正循环边界为i < length,同时打印索引和对应元素值,方便查看数据结构 for(int i = 0; i < coordinates.length; ++i){ print('index: $i, value: ${coordinates[i]}'); } }
补充建议
- 可以引入
path包的join方法拼接路径,自动适配不同操作系统的路径分隔符,避免硬编码/带来的兼容性问题。 - 建议为文件读取、JSON解析逻辑添加
try-catch异常捕获,处理文件不存在、JSON格式不合法、字段类型不匹配等边界场景,避免程序直接崩溃。 - 如果JSON中
elements字段下的元素不是num类型,直接调用cast<double>()会触发类型转换异常,需要根据实际JSON结构调整解析逻辑。
内容的提问来源于stack exchange,提问作者mchd
相关产品推荐
相关产品推荐

