【问题标题】:Deserialize json/yaml from binary stream which contains other data从包含其他数据的二进制流中反序列化 json/yaml
【发布时间】:2016-10-01 12:33:07
【问题描述】:

假设我有一个二进制流stream,并按如下方式生成它。

stream.write('lol'.encode())
yaml.dump(some_obj, stream)
stream.write('awesome'.encode())

那么我是否必须为流编写某种自定义解析器,或者我可以恢复some_obj,如下所示。

stream.read(3)
recovered = yaml.load(stream)
stream.read(7)

如果这不适用于 yaml 序列化,它是否适用于 json 序列化?

【问题讨论】:

    标签: python json serialization yaml


    【解决方案1】:

    你不能做你想做的事,因为 YAML 解析器会消耗完整的流,即使你转储一个显式结束(yaml.dump(some_obj, stream, explicit_end=True)(本质上在awesome 之前插入...\n),它在编写@ 时也不起作用987654324@(文档分隔符)。当您使用 yaml.load()yaml.load_all() 时,YAML 解析器都会使用单词 awesome¹。

    前面的部分工作正常,因此您可以考虑执行以下操作:

    import ruamel.yaml as yaml
    
    file_name = 'test.comb'
    
    some_obj = dict(a = [1, 2], b = {3: 42})
    
    with open(file_name, 'w') as stream:
        stream.write('lol'.encode())
        yaml.dump(some_obj, stream, explicit_end=True)
        stream.write('awesome'.encode())
    
    
    with open(file_name) as stream:
        assert stream.read(3) == 'lol'
        stream_data = ''
        while True:
            stream_data += stream.read(1)
            if stream_data[-4:] == '...\n':
                break
        recovered = yaml.load(stream_data)
        assert stream.read(7) == 'awesome'
    
    print(recovered)
    

    它给出(在 Python2 中):

    {'a': [1, 2], 'b': {3: 42}}
    

    文件内容为:

    lola: [1, 2]
    b: {3: 42}
    ...
    awesome
    

    我使用了类似的技术,但是读取带有for line in stream 的行,它不能与正常的read() 操作结合使用,对于具有带有元数据的 YAML 标头的文件,后跟普通文本(非缩进,因此 emacs 可以正确努力工作)。


    ¹ 我认为读取流结束标记 (...) 是 Python YAML 解析器中的一个错误,因此我将尝试在下一个版本中修复此问题。

    【讨论】:

      猜你喜欢
      • 2016-09-15
      • 2014-11-28
      • 1970-01-01
      • 2016-09-29
      • 2018-03-20
      • 1970-01-01
      • 2019-01-19
      • 2014-01-04
      • 1970-01-01
      相关资源
      最近更新 更多