【问题标题】:Unable to write to JSON file in dart using flutter无法使用颤振写入飞镖中的 JSON 文件
【发布时间】:2019-01-07 08:27:18
【问题描述】:

我能够读取 JSON 文件,但似乎无法写入或更新 JSON 文件。我能够更新 JSON 字符串,但似乎无法将我的 json 字符串写入文件。下面的代码是我用来读取文件的代码。但是,我无法写入同一个文件。

new ListTile(

        title: new Text("Close" ),
        trailing: new Icon(Icons.cancel),
        onTap: loadpos,
      )
class NewPage {
  final String title;
  final Color color;
  NewPage({this.title,this.color});
}


Future <String> _loadpos() async{
    return await rootBundle.loadString('assets/button.json');
  }

Future <String> loadpos() async{
  String jsonword = await _loadpos();
//  _parseJsonForPos(jsonword);
  List data = json.decode(jsonword);
 // data[0]["backgrndcolor"] = "black";
  print(data[0]["navbar"]);
}


String _parseJsonForPos(String jsonString) {
  List data = json.decode(jsonString);

  print(data[0]["_value"]);

}

资产文件:(button.json)

[{“导航栏”:“顶部”}]

打印值:

Performing hot reload...
Reloaded 5 of 430 libraries in 1,474ms.
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/flutter (15546): top
I/art     (15546): Background sticky concurrent mark sweep GC freed 222431(11MB) AllocSpace objects, 0(0B) LOS objects, 93% free, 911KB/12MB, paused 553us total 113.423ms
I/art     (15546): Background partial concurrent mark sweep GC freed 222396(11MB) AllocSpace objects, 0(0B) LOS objects, 92% free, 1027KB/13MB, paused 523us total 124.949ms
Lost connection to device.
  • 我目前面临的问题是我无法将值写入和更新到 JSON 文件。

为了尝试另一种读取和写入 JSON 文件的方法,我使用了另一种方法来创建和写入 JSON 文件,但我发现这只是临时存储和读取而不写入 JSON 文件.

根据我对 Android 的理解,getApplicationDocumentsDirectory() 方法返回 AppData 目录。但是,当我在手机上搜索此目录时,我找不到我的 button.json 文件。

import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(new MaterialApp(
    home: new Home(),
  ));
}

class Home extends StatefulWidget {
  @override
  State createState() => new HomeState();
}

class HomeState extends State<Home> {

  TextEditingController keyInputController = new TextEditingController();
  TextEditingController valueInputController = new TextEditingController();

  File jsonFile;
  Directory dir;
  String fileName = "button.json";
  bool fileExists = false;
  Map<String, dynamic> fileContent;

  @override
  void initState() {
    super.initState();
    getApplicationDocumentsDirectory().then((Directory directory) {
      dir = directory;
      jsonFile = new File(dir.path + "/" + fileName);
      fileExists = jsonFile.existsSync();
      if (fileExists) this.setState(() => fileContent = JSON.decode(jsonFile.readAsStringSync()));
    });
  }

  @override
  void dispose() {
    keyInputController.dispose();
    valueInputController.dispose();
    super.dispose();
  }

  void createFile(Map<String, dynamic> 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(String key, dynamic value) {
    print("Writing to file!");
    Map<String, dynamic> content = {key: value};
    if (fileExists) {
      print("File exists");
      Map<String, dynamic> 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);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("JSON Tutorial"),),
      body: new Column(
        children: <Widget>[
          new Padding(padding: new EdgeInsets.only(top: 10.0)),
          new Text("File content: ", style: new TextStyle(fontWeight: FontWeight.bold),),
          new Text(fileContent.toString()),
          new Padding(padding: new EdgeInsets.only(top: 10.0)),
          new Text("Add to JSON file: "),
          new TextField(
            controller: keyInputController,
          ),
          new TextField(
            controller: valueInputController,
          ),
          new Padding(padding: new EdgeInsets.only(top: 20.0)),
          new RaisedButton(
            child: new Text("Add key, value pair"),
            onPressed: () => writeToFile(keyInputController.text, valueInputController.text),
          )
        ],
      ),
    );
  }
}

TL;DR:我能够创建一个 json 字符串,但无法将其写入 json 文件

【问题讨论】:

  • 我不太确定您要完成什么,但您可能需要写入应用程序的存储空间。这可能不会映射到设备上的文件。我看到了这个建议flutter.io/flutter-for-react-native/#local-storage。可能还有其他库用于将大量数据写入应用程序的存储。如果您需要将真实文件读/写到文件系统,docs.flutter.io/flutter/dart-io/dart-io-library.html 应该可以工作。尝试使用它时是否遇到特定错误?我不确定目录和应用程序权限如何与它一起使用。
  • 对不起,如果我的描述不够清楚。本质上,我想做的是读取一个 JSON 文件,然后如果需要更新该 JSON 文件中的值。到目前为止,我已经能够读取 JSON 文件,对 JSON 字符串进行编码,但无法将 JSON 字符串写入 JSON 文件。谢谢
  • JSON 文件从何而来?我不确定您是否可以编辑资产目录中的文件。有人可以纠正我,但通常如果您要保存用户首选项或使用 iOS/Android 本机存储 API 的东西。如果您正在向/从用户的 SD 卡读取/写入诸如 word 文档、PDF、图像或一些大文件之类的内容,那么您可以获得访问文件系统的权限并这样做。
  • 啊。我想你是正确的。这很有意义。我认为这也是我观看的 youtube 教程使用 getApplicationDocumentsDirectory() 方法的原因。根据使用 AAndroid 或 iOS API 将文件存储在您提到的适当目录中的颤振文档。我想我使用 Assests 来保存用户首选项文件的方法是错误的。谢谢!
  • 使用shared_preferences 保存用户首选项文件。

标签: json dart flutter


【解决方案1】:

创建的json文件无法访问的原因是因为使用了getApplicationDocumentsDirectory()。路径是 '/data/user/0/{PACKAGE_NAME}/app_flutter',我认为使用设备的文件浏览器无法访问它。

我建议使用getExternalStorageDirectory(),因为它将文件写入“/storage/emulated/0/Android/data/{PACKAGE_NAME}/files”并且很容易访问。

这是运行您提供的重现的一些屏幕截图。

可以使用文件浏览器访问 Json 文件

打开json文件显示文件中写入的相同字符串

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-21
    • 2020-12-25
    • 2023-03-05
    • 2020-09-12
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多