如何正确写入JSON文件?解决类型不匹配异常问题
解决Dart中
_InternalLinkedHashMap<dynamic, dynamic>与Map<String, dynamic>类型不匹配的异常 这个问题我之前也碰到过,核心原因其实很明确:JSON规范要求所有键必须是字符串类型,但你用了数字3423作为Map的键,这就导致序列化/反序列化时出现类型冲突:
- 调用
json.decode()读取文件内容时,返回的是Map<String, dynamic>(因为JSON解析后所有键都会是字符串) - 但你创建的
content对象是Map<dynamic, dynamic>(键是int类型),调用addAll()时两种Map类型无法兼容,直接抛出了类型转换异常。
解决步骤
只需要确保所有Map的键都是字符串类型,同时在代码里明确类型约束,就能解决问题:
- 修改
writeToFile方法,将数字键转为字符串
void writeToFile(var key, var value) { print("Writing to file!"); // 把数字key转为字符串,匹配JSON的键类型要求 String stringKey = key.toString(); Map<String, dynamic> content = {stringKey: value}; if (fileExists) { print("File exists"); // 明确指定解码后的类型为Map<String, dynamic>,避免动态类型隐患 Map<String, dynamic> jsonFileContent = json.decode(jsonFile.readAsStringSync()) as Map<String, dynamic>; jsonFileContent.addAll(content); jsonFile.writeAsStringSync(json.encode(jsonFileContent)); } else { print("File does not exist!"); createFile(content, dir, fileName); } // 更新状态时,把Map的values转为List,更符合你fileContent的List<Map>类型 this.setState(() { Map<String, dynamic> decoded = json.decode(jsonFile.readAsStringSync()) as Map<String, dynamic>; fileContent = decoded.values.toList().cast<Map>(); }); print(fileContent); }
- 初始化时明确类型转换
在initState里读取文件内容时,也加上明确的类型转换,避免动态类型带来的隐藏问题:
@override void initState() { super.initState(); getApplicationDocumentsDirectory().then((Directory directory) { dir = directory; jsonFile = File(dir.path + "/" + fileName); fileExists = jsonFile.existsSync(); if (fileExists) { this.setState(() { Map<String, dynamic> decodedContent = json.decode(jsonFile.readAsStringSync()) as Map<String, dynamic>; fileContent = decodedContent.values.toList().cast<Map>(); }); } }); }
- 增强
createFile的类型安全性
把createFile的参数类型明确为Map<String, dynamic>,提前约束输入类型:
void createFile(Map<String, dynamic> content, Directory dir, String fileName) { print("Creating file!"); File file = File(dir.path + "/" + fileName); file.createSync(); fileExists = true; file.writeAsStringSync(json.encode(content)); }
补充说明
这样修改后,所有操作的Map键都是字符串类型,完全符合JSON规范,类型不匹配的异常就会消失。另外,在Dart中尽量明确指定变量类型,能帮你在编译阶段就发现很多类型问题,避免运行时踩坑。
内容的提问来源于stack exchange,提问作者Hassico
相关产品推荐
相关产品推荐

