如何将含JSON字符串的JSON列表写入.json文件并实现读取与反序列化?
问题分析与修复方案
你的代码存在几个核心问题导致读写逻辑失效:
readHistory在文件不存在时返回[''],会让后续逻辑误判为已有内容,且属于无效JSON结构writeHistory对readHistory返回的结果重复执行jsonDecode,会抛出解码错误(因为readHistory已经返回了解码后的列表)- 错误地将
map转为JSON字符串再存入列表,导致文件存储的是字符串数组而非对象数组,后续遍历还要额外解码,完全冗余
修改后的代码
import 'dart:convert' as convert; import 'dart:io'; import 'package:path_provider/path_provider.dart'; // 保持原有文件获取逻辑,这里补充完整示例 Future<File> get _localFile async { final directory = await getApplicationDocumentsDirectory(); return File('${directory.path}/history.json'); } Future writeHistory(Map<String, dynamic>? map) async { if (map == null) return; // 空map直接返回,避免写入无效数据 final file = await _localFile; // 读取已有的历史列表,空文件或不存在时返回空列表 final List<dynamic> infoList = await readHistory(); // 直接将map添加到列表,无需转字符串 infoList.add(map); // 将整个列表序列化为JSON字符串写入文件 return file.writeAsString(convert.jsonEncode(infoList), mode: FileMode.write); } Future<List<dynamic>> readHistory() async { try { final file = await _localFile; if (!await file.exists()) return []; // 文件不存在返回空列表 final contents = await file.readAsString(); if (contents.isEmpty) return []; // 文件为空返回空列表 // 解码为列表,确保是数组结构 final decoded = convert.jsonDecode(contents); return decoded is List ? decoded : []; } catch (e) { // 解码失败或其他异常统一返回空列表 return []; } }
读取并遍历的示例
void loadAndTraverseHistory() async { final List<dynamic> historyList = await readHistory(); for (var item in historyList) { // 转为Map类型后使用 Map<String, dynamic> historyItem = item as Map<String, dynamic>; // 这里处理每个历史项,比如打印内容 print(historyItem); } }
关键修复说明
- 初始状态修正:文件不存在或为空时返回空列表,避免无效数据干扰后续逻辑
- 简化编码解码流程:直接操作Map对象组成的列表,写入时整体转JSON,读取时直接得到对象列表
- 空值防护:写入前先判断传入的map是否为空,防止写入null
- 类型安全校验:读取时校验解码结果是否为列表,避免类型转换错误
内容的提问来源于stack exchange,提问作者Ezra0M
相关产品推荐
相关产品推荐

