【问题标题】:How to write a map to a YAML file in Dart如何在 Dart 中将映射写入 YAML 文件
【发布时间】:2020-05-19 22:05:46
【问题描述】:

我在 Dart 中有一个键值对映射。我想将其转换为YAML 并写入文件。

我尝试使用 dart 库中的 YAML 包,但它只提供从文件加载 YAML 数据的方法。没有提及如何将其写回YAML 文件。

这是一个例子:

void main() {
  var map = {
    "name": "abc",
    "type": "unknown",
    "internal":{
      "name": "xyz"
    }
  };
  print(map);
}

预期输出: example.yaml

name: abc
type: unknown
internal:
  name: xyz

如何将 dart map 转换为 YAML 并写入文件?

【问题讨论】:

    标签: dart yaml dart-io


    【解决方案1】:

    package:yaml 没有 YAML 写入功能。您可能需要寻找另一个可以做到这一点的包 - 或者自己编写。

    作为权宜之计,请记住 JSON 是有效的 YAML,因此您始终可以将 JSON 写入 .yaml 文件,并且它应该适用于任何 YAML 解析器。

    【讨论】:

    • 是的,Kevin Moore 很到位。
    • 什么??您能否详细说明如何将 json 写入 yaml 文件,使其成为有效的 yaml?
    • @Yadu - YAML 是 JSON 的超集。任何有效的 JSON 文档都是有效的 YAML 文档 AFAIK
    • 只在解析时有效,也就是说无法将json写入yaml。
    【解决方案2】:

    我遇到了同样的问题,最后拼凑了一个简单的作家:

      // Save the updated configuration settings to the config file
      void saveConfig() {
        var file = _configFile;
    
        // truncate existing configuration
        file.writeAsStringSync('');
    
        // Write out new YAML document from JSON map
        final config = configToJson();
        config.forEach((key, value) {
          if (value is Map) {
            file.writeAsStringSync('\n$key:\n', mode: FileMode.writeOnlyAppend);
            value.forEach((subkey, subvalue) {
              file.writeAsStringSync('  $subkey: $subvalue\n',
                  mode: FileMode.writeOnlyAppend);
            });
          } else {
            file.writeAsStringSync('$key: $value\n',
                mode: FileMode.writeOnlyAppend);
          }
        });
      }
    

    【讨论】:

      【解决方案3】:

      回复有点晚了,但对于其他看到这个问题的人来说,我已经写了这门课。它可能并不完美,但它适用于我正在做的事情,而且我还没有发现任何问题。可能在编写测试后最终将其做成一个包。

      class YamlWriter {
        /// The amount of spaces for each level.
        final int spaces;
      
        /// Initialize the writer with the amount of [spaces] per level.
        YamlWriter({
          this.spaces = 2,
        });
      
        /// Write a dart structure to a YAML string. [yaml] should be a [Map] or [List].
        String write(dynamic yaml) {
          return _writeInternal(yaml).trim();
        }
      
        /// Write a dart structure to a YAML string. [yaml] should be a [Map] or [List].
        String _writeInternal(dynamic yaml, { int indent = 0 }) {
          String str = '';
      
          if (yaml is List) {
            str += _writeList(yaml, indent: indent);
          } else if (yaml is Map) {
            str += _writeMap(yaml, indent: indent);
          } else if (yaml is String) {
            str += "\"${yaml.replaceAll("\"", "\\\"")}\"";
          } else {
            str += yaml.toString();
          }
      
      
          return str;
        }
      
        /// Write a list to a YAML string.
        /// Pass the list in as [yaml] and indent it to the [indent] level.
        String _writeList(List yaml, { int indent = 0 }) {
          String str = '\n';
      
          for (var item in yaml) {
            str += "${_indent(indent)}- ${_writeInternal(item, indent: indent + 1)}\n";
          }
      
          return str;
        }
      
        /// Write a map to a YAML string.
        /// Pass the map in as [yaml] and indent it to the [indent] level.
        String _writeMap(Map yaml, { int indent = 0 }) {
          String str = '\n';
      
          for (var key in yaml.keys) {
            var value = yaml[key];
            str += "${_indent(indent)}${key.toString()}: ${_writeInternal(value, indent: indent + 1)}\n";
          }
      
          return str;
        }
      
        /// Create an indented string for the level with the spaces config.
        /// [indent] is the level of indent whereas [spaces] is the
        /// amount of spaces that the string should be indented by.
        String _indent(int indent) {
          return ''.padLeft(indent * spaces, ' ');
        }
      }
      

      用法:

      final writer = YamlWriter();
      String yaml = writer.write({
        'string': 'Foo',
        'int': 1,
        'double': 3.14,
        'boolean': true,
        'list': [
          'Item One',
          'Item Two',
          true,
          'Item Four',
        ],
        'map': {
          'foo': 'bar',
          'list': ['Foo', 'Bar'],
        },
      });
      
      File file = File('/path/to/file.yaml');
      file.createSync();
      file.writeAsStringSync(yaml);
      

      输出:

      string: "Foo"
      int: 1
      double: 3.14
      boolean: true
      list: 
        - "Item One"
        - "Item Two"
        - true
        - "Item Four"
      
      map: 
        foo: "bar"
        list: 
          - "Foo"
          - "Bar"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-07
        • 1970-01-01
        • 1970-01-01
        • 2017-03-14
        • 2019-01-08
        • 2021-11-11
        • 1970-01-01
        • 2018-11-28
        相关资源
        最近更新 更多