保存FireImage对象为JSON文件后读取解析遇FormatException错误求助
问题分析与解决
你遇到的FormatException问题根源很明确:你没有读取文件里的实际JSON内容,而是把File对象本身转成了字符串。当你调用imageFile.toString()时,返回的是类似File: '/data/user/0/com.yourapp/app_flutter/json_cache/your_image_name'这样的文件路径描述字符串,根本不是JSON格式的内容,所以json解析器直接报错了。
修复步骤
- 异步读取文件内容:文件IO是异步操作,必须用
readAsString()方法获取文件里的文本内容,而不是直接转File对象为字符串。 - 将读取函数改为异步:因为涉及异步IO操作,你的
fireImageFromEntity方法需要改成async函数,返回Future<FireImage>。 - 增加基础错误处理(可选但推荐):处理文件不存在、读取失败等情况,避免崩溃。
修改后的完整代码
保存代码(原代码优化版)
Future<File> saveJsonFile(FireImage image) async { final appDir = await getApplicationDocumentsDirectory(); jsonDirectory = '${appDir.path}/json_cache/'; final filePath = '$jsonDirectory${image.name}'; print("saving json to $filePath"); // 确保目录存在,然后写入JSON final file = File(filePath); await file.create(recursive: true); return file.writeAsString(json.encode(image.toJson())); }
注:为了确保序列化正常,建议给
FireImage类添加序列化和反序列化方法,示例如下:class FireImage { final String name; final DateTime dateTime; final int count; final String url; FireImage(this.name, this.dateTime, this.count, this.url); // 序列化方法 Map<String, dynamic> toJson() { return { 'name': name, 'dateTime': dateTime.millisecondsSinceEpoch, 'count': count, 'url': url, }; } // 反序列化构造函数 FireImage.fromJson(Map<String, dynamic> json) : name = json['name'], dateTime = DateTime.fromMillisecondsSinceEpoch(json['dateTime']), count = json['count'], url = json['url']; }
修复后的读取代码
Future<FireImage> fireImageFromEntity(String fileName) async { final filePath = "$jsonDirectory$fileName"; final imageFile = File(filePath); // 先检查文件是否存在 if (!await imageFile.exists()) { throw Exception("File $fileName not found in cache"); } // 读取文件的实际JSON内容 final imageJsonString = await imageFile.readAsString(); final imageJson = json.decode(imageJsonString); // 用反序列化构造函数创建对象(更简洁的方式) return FireImage.fromJson(imageJson); // 也可以保留你原来的手动赋值方式: // String name = imageJson["name"]; // DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(imageJson["dateTime"]); // int count = imageJson["count"]; // String url = imageJson["url"]; // return FireImage(name, dateTime, count, url); }
调用方式
因为读取函数现在是异步的,调用时需要用await或者.then():
// 示例调用 try { FireImage image = await fireImageFromEntity("my_image.json"); // 处理读取到的image对象 } catch (e) { print("读取缓存失败:$e"); }
这样修改后,就能正确读取文件里的JSON内容并解析成FireImage对象了。
内容的提问来源于stack exchange,提问作者Wazza
相关产品推荐
相关产品推荐

