首页 > 解决方案 > 如何正确写入 json 文件?

问题描述

我将用户收藏夹存储到 json 文件中,但出现以下错误:

未处理的异常:类型“_InternalLinkedHashMap<dynamic, dynamic>”不是“other”的“Map<String, dynamic>”类型的子类型

我将以下数据添加到文件中:

{
 3423: {
'ID': 3423,
'Title': 'Jupiter Ascending',
'Image': 'https://...'
}
}

代码是:

File jsonFile;
Directory dir;
String fileName = "Reading.json";
bool fileExists = false;
List<Map> fileContent;

@override
void initState() {
  super.initState();
  /*to store files temporary we use getTemporaryDirectory() but we need
    permanent storage so we use getApplicationDocumentsDirectory() */
  getApplicationDocumentsDirectory().then((Directory directory) {
    dir = directory;
    jsonFile = new File(dir.path + "/" + fileName);
    fileExists = jsonFile.existsSync();
    if (fileExists)
      this.setState(
          () => fileContent = json.decode(jsonFile.readAsStringSync()));
  });
}

void createFile(Map content, Directory dir, String fileName) {
  print("Creating file!");
  File file = new File(dir.path + "/" + fileName);
  file.createSync();
  fileExists = true;
  file.writeAsStringSync(json.encode(content));
}

void writeToFile(var key, var value) {
  print("Writing to file!");
  Map content = {key: value};
  if (fileExists) {
    print("File exists");
    Map jsonFileContent = json.decode(jsonFile.readAsStringSync());
    jsonFileContent.addAll(content);
    jsonFile.writeAsStringSync(json.encode(jsonFileContent));
  } else {
    print("File does not exist!");
    createFile(content, dir, fileName);
  }
  this.setState(() => fileContent = json.decode(jsonFile.readAsStringSync()));
  print(fileContent);
}

我很困惑,不知道如何解决这个问题。

标签: jsonflutterdart

解决方案


你已经删除了在你的方法中输入的任何痕迹,writeToFile这使得 Dart 无法帮助你。问题来自:

void writeToFile(var key, var value) {
  print("Writing to file!");
  Map content = {key: value};
...

首先,永远不要var在方法上用作参数类型。这真的很糟糕,因为您允许所有类型都不是您想要的。

在这种情况下,结果json.decode(jsonFile.readAsStringSync())将是Map<String, dynamic>运行时的实例。

但是您正在创建的 MapMap content = {key: value};将属于该类型Map<dynamic, dynamic>,因为它在编译代码时无法预测键和值的类型。

由于您不能将 a 的内容Map<dynamic, dynamic>放入Map<String, dynamic>您会得到一个错误。

您可以做的是key至少制作一个字符串,例如:

void writeToFile(String key, var value) {
  print("Writing to file!");
  final content = {key: value};
...

我还要说,如果您正在使用varfinal不是尝试手动输入类型,您可以帮助自己。如果您想要类型,那很好,但是您确实需要显式编写类型的正确通用部分。

例如这是错误的:

Map jsonFileContent = json.decode(jsonFile.readAsStringSync());

因为你把通用部分扔掉了。相反,它应该是:

Map<String, dynamic> jsonFileContent = json.decode(jsonFile.readAsStringSync());

或者让 Dart 处理这些东西:

final jsonFileContent = json.decode(jsonFile.readAsStringSync());

推荐阅读