Flutter中JSON解析与文件追加二次运行失败问题求助
问题:JSON文件读写转换模型时类型不匹配错误
问题场景
尝试实现以下流程处理JSON文件:
- 流程1:文件已存在 → 读取并解码JSON → 转为模型对象 → 添加新元素 → 转回JSON并保存
- 流程2:文件不存在 → 创建文件并写入模板JSON → 后续同流程1
首次运行(流程2)正常,但二次运行(流程1)抛出错误:
E/flutter (13140): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<dynamic, dynamic>' E/flutter (13140): #0 FileController.writeSingleResponseToFile (package:reefcommander/controllers/FileController.dart:33:39) E/flutter (13140): <asynchronous suspension>
错误原因
- 保存逻辑错误:首次保存时,错误地将
existingdata.toJson()的结果先转成字符串,再用jsonEncode处理,导致最终写入文件的是被字符串包裹的JSON。二次读取时,jsonDecode解析后得到的是一个字符串,而非预期的Map,强转时触发类型错误。 - 模型转换错误:JSON结构是单个
ReadingsData对象,而非数组,但代码中错误地用r[0]去访问,导致类型不匹配。
修正后的代码
修改FileController.dart中的writeSingleResponseToFile方法
static writeSingleResponseToFile(SingleDataReqResponse resp) async { final File file = await checkFileExists(resp.name.toString()); // 读取文件内容并解码为Map var jsonContent = jsonDecode(await file.readAsString()) as Map<String, dynamic>; // 直接用整个Map初始化ReadingsData,不需要r[0] ReadingsData existingdata = ReadingsData.fromJson(jsonContent); existingdata.results!.add(Results(stamp: resp.stamp, value: resp.value)); // 直接将toJson()的Map结果编码为JSON字符串,不需要额外转toString() await file.writeAsString(jsonEncode(existingdata.toJson())); }
额外优化点
checkFileExists方法中调用readFile(type)是异步方法,但未加await,可能导致文件创建不及时,建议修改:
static Future<File> checkFileExists(String type) async { await readFile(type); // 添加await确保文件操作完成 final Directory? directory = Platform.isAndroid ? await getExternalStorageDirectory() : await getApplicationSupportDirectory(); final String filename = '${directory!.path}/${date}_$type.json'; return File(filename); }
- 处理
results为空的情况,避免空指针:在ReadingsData.fromJson中确保results默认初始化空数组,或者在添加元素前做非空判断。
验证逻辑
修正后,首次运行写入标准JSON对象,二次读取时jsonDecode能正确解析为Map,转换为ReadingsData对象后可正常添加新元素并保存。
内容的提问来源于stack exchange,提问作者James P
相关产品推荐
相关产品推荐

