You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter读取JSON时抛出FormatException: Unexpected end of input错误

Flutter JSON解析FormatException: Unexpected end of input 问题修复

问题现象

Flutter运行时抛出如下错误:

[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: FormatException: Unexpected end of input (at character 88586)
[        ] E/flutter ( 5286): ...820457458, -0.09168463200330734, 0.9341723918914795, 0.9910492897033691]}",

原有实现逻辑:

  1. 手动拼接字符串构造JSON片段,存入列表:
for(var i = 0 ; i <=32; ++i) {
            String entry = '{contents: ['
                '${contentList.content[i].x.toString()}, '
                '${contentList.content[i].y.toString()}, '
                '${contentList.content[i].z.toString()}, '
                '${contentList.content[i].visibility.toString()}, '
                '${contentList.content[i].presence.toString()}]}';
            content_collector.add(entry);
          }
  1. 将字符串列表传入方法写入JSON文件:
Future<File> saveToJSONFile(List<String> contents_list, String filename) async {
    String encodedContents = jsonEncode(contents_list);
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path + '/' + filename;

    return await File(appDocPath).writeAsString(encodedContents);
  }
  1. 读取文件并解析JSON:
void readJSON(String path) async {

    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path + '/' + path;

    String response = await File(appDocPath).readAsString();
    final data = await json.decode(response.toString());

  }

执行readJSON时抛出上述格式异常,手动排查未定位到原因。

错误原因

  • 核心问题是手动拼接JSON字符串本身不符合JSON语法规范:标准JSON要求所有对象的键必须用双引号包裹,你拼接的{contents: [xxx]}中contents未加双引号,属于非法JSON结构。
  • 序列化逻辑存在矛盾:你将手动拼接的字符串存入列表后调用jsonEncode,此时jsonEncode会把每个字符串当成普通文本值做转义处理,而非按JSON对象序列化,最终生成的文件是字符串数组而非预期的对象数组;如果拼接过程中数值转字符串出现特殊字符、或者文件写入未完全刷盘,就会出现内容截断,触发"输入意外结束"的解析错误。

修复方案

禁止手动拼接JSON字符串,所有JSON序列化操作直接交给内置jsonEncode方法处理,只需要传入结构化的Dart基础类型(Map、List、数字、字符串、布尔值、null)即可自动生成完全合规的JSON内容,从根源避免格式问题。

  1. 替换手动拼接字符串的逻辑,直接构造结构化数据列表:
// 初始化结构化列表,不需要存字符串
List<Map<String, List<num>>> content_collector = [];
for(var i = 0 ; i <=32; ++i) {
  final item = contentList.content[i];
  content_collector.add({
    "contents": [
      item.x,
      item.y,
      item.z,
      item.visibility,
      item.presence
    ]
  });
}
  1. 优化写入方法,增加刷盘参数避免大文件写入截断:
Future<File> saveToJSONFile(List<Map<String, List<num>>> contents_list, String filename) async {
  String encodedContents = jsonEncode(contents_list);
  Directory appDocDir = await getApplicationDocumentsDirectory();
  String appDocPath = '${appDocDir.path}/$filename';
  // flush: true 确保内容完全写入磁盘后再返回
  return await File(appDocPath).writeAsString(encodedContents, flush: true);
}
  1. 简化读取逻辑,移除多余的toString()调用:
void readJSON(String path) async {
  Directory appDocDir = await getApplicationDocumentsDirectory();
  String appDocPath = '${appDocDir.path}/$path';
  String response = await File(appDocPath).readAsString();
  // 解析后直接得到结构化的List对象,可按需取值
  final data = json.decode(response);
}

内容的提问来源于stack exchange,提问作者mchd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 18:31:12