代码之家  ›  专栏  ›  技术社区  ›  Nikko

Python中如何在BytesIO内部进行json转储?

  •  0
  • Nikko  · 技术社区  · 5 年前

    我试图在ZipFile BytesIO进程中编写一个json。它是这样的:

    import io
    from zipfile import ZipFile
    import json
    
    in_memory_zip = io.BytesIO()
    with ZipFile(in_memory_zip, 'w') as zipfile:
        with zipfile.open("1/1.json", 'w') as json_file:
            data = {'key': 1}
            json.dump(data, json_file, ensure_ascii=False, indent=4)
    

    它稍后保存在Django文件字段中。然而,事实并非如此 dump 数据进入 json_file 。发现它很难,因为它没有报告错误消息。

    0 回复  |  直到 5 年前
        1
  •  3
  •   Nikko    5 年前

    你的代码“阴影” zipfile ,这本身不会有问题,但如果需要的话会造成问题 zip文件 稍后在代码中。一般来说,不要隐藏标准库标识符和Python关键字。

    为什么这是一个问题,我不知道,但它似乎 json.dump 期望从文件指针中得到类似文件的对象 ZipFile.open() 得到你没有的。

    这是如何解决这个问题的:

    import io
    from zipfile import ZipFile
    import json
    
    in_memory_zip = io.BytesIO()
    with ZipFile(in_memory_zip, 'w') as zf:
        with zf.open("1/1.json", 'w') as json_file:
            data = {'key': 1}
            data_bytes = json.dumps(data, ensure_ascii=False, indent=4).encode('utf-8')
            json_file.write(data_bytes)
    
        2
  •  2
  •   Алексей Киричун    2 年前

    原始代码失败的原因是 ZipFile 期望二进制数据作为输入,而 json.dump 需要一个接受“文本”数据的类文件对象( str ,不 bytes ). 你可能会想到这个物体 zf.open() 返回时,它就像是一个打开的文件 "wb" 模式。

    因此,这里正确的做法是将类似文件的对象包装起来,以呈现面向文本的输出 json.dump 。而且,由于任何文本都必须编码为字节,因此您必须从中获取解决方案 encodings 图书馆。

    因此,这是有效的:

    import io
    from zipfile import ZipFile
    import json
    import encodings
    
    in_memory_zip = io.BytesIO()
    with ZipFile(in_memory_zip, 'w') as zipfile:
        with zipfile.open("1/1.json", 'w') as json_file:
            data = {'key': 1}
            json_writer = encodings.utf_8.StreamWriter(json_file)
            # JSON spec literally fixes interchange encoding as UTF-8: https://datatracker.ietf.org/doc/html/rfc8259#section-8.1
            json.dump(data, json_writer, ensure_ascii=False, indent=4)
    
    推荐文章