Python - 如何一次性有效地写入/读取压缩档案中的 JSON 文件?

问题描述 投票:0回答:2

我正在使用 Python 3.8,并且希望将数据字典保存到 JSON 文件中,该文件一次性压缩在存档中,最好仅使用 Python 标准库。例如,这意味着我的数据保存在文件 data.json 中,该文件包含在存档

compressed_data.zip
中。
现在,这就是我所得到的:

#!/usr/bin/env python3 # -*- coding: utf-8 -*- # SPDX-License-Identifier: GPL-3.0-or-later # Python Standard Library imports import json import zlib # Prepare some data data: dict = { "common_name": "Brongersma's short-tailed python", "scientific_name": "Python brongersmai", "length": 290 } # Save data to a JSON file with open("data.json", "w", encoding="utf-8") as output_JSON_file: json.dump(data, output_JSON_file, ensure_ascii=False, indent=4) # Open saved JSON then compress it with open ("data.json", "r", encoding="utf-8") as input_JSON_file: data: dict = json.load(input_JSON_file) # Data needs to be saved as bytes to be compressed data_bytes: bytes = json.dumps(data, indent=4).encode("utf-8") compressed_data = zlib.compress(data_bytes, level=zlib.Z_BEST_COMPRESSION) with open ("compressed_data.zip" , "wb") as output_zlib_file: output_zlib_file.write(compressed_data)

这不会产生我想要的结果,因为
(a)

它首先保存JSON文件,打开它,然后将数据保存到一个压缩文件中,最后在磁盘上有two文件; (b) 压缩文件是压缩的 数据,但不是可以在任何通用 GUI 压缩/解压缩程序中打开的 ZIP 文件中的 JSON 文件。 所以我的问题是:

    有没有一种方法可以一次性实现我的目标,而无需先保存 JSON 文件,然后将其压缩到存档中? (即
  1. .json

    文件永远不会接触磁盘,只有

    .zip
    文件接触磁盘)
    
    

  2. 如何执行相反的操作

    并将存档直接解压缩到 Python 中的字典中?

  3. 如果没有办法一次性完成 1. 和 2.,那么相对有效的方法是什么?
  4. 注意:理想情况下,我想要一个仅使用 Python 3.8 标准库的解决方案,并且压缩存档不必使用
zlib

库或 ZIP 文件。

其他高压缩比方法也可以
谢谢!

python json performance compression
2个回答
6
投票

#!/usr/bin/env python3 # -*- coding: utf-8 -*- # SPDX-License-Identifier: GPL-3.0-or-later # Python's internal `zipfile` module import json import zipfile # Prepare some data data: dict = { "common_name": "Brongersma's short-tailed python", "scientific_name": "Python brongersmai", "length": 290 } # Use the `zipfile` module # `compresslevel` was added in Python 3.7 with zipfile.ZipFile("compressed_data.zip", mode="w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as zip_file: # Dump JSON data dumped_JSON: str = json.dumps(data, ensure_ascii=False, indent=4) # Write the JSON data into `data.json` *inside* the ZIP file zip_file.writestr("data.json", data=dumped_JSON) # Test integrity of compressed archive zip_file.testzip()

此解决方案使用 Python 标准库的内部 

zipfile 模块

。关键是 
zip_file.writestr(),它允许您基本上写入 ZIP 文件
内部
的文件。 如果还有其他解决方案,请分享!


0
投票

import json from codecs import getwriter from typing import IO from zipfile import ZIP_DEFLATED, ZipFile class ZipFileWrapper(ZipFile): def open(self, name="data", mode="r", pwd=None, **kwargs): return super().open(name=name, mode=mode, pwd=pwd, **kwargs) def read(self): return super().read(name="data") def _json_dump_bytes(fp: IO, obj): StreamWriter = getwriter("utf-8") return json.dump(fp=StreamWriter(fp), obj=obj) def json_dump_zip(fp: IO, obj): with ZipFileWrapper( fp, mode="w", compression=ZIP_DEFLATED, compresslevel=9 ) as zip_file: with zip_file.open(mode="w") as _fp: json_dump_bytes(fp=_fp, obj=obj) def json_load_zip(fp: IO): with ZipFileWrapper(fp, mode="r") as zip_file: return json.load(zip_file)

用途:

obj = {"foo": "bar"} with open("my_file.zip", "wb") as f: json_dump_zip(fp=f, obj=obj) with open("my_file.zip, "rb") as f: loaded_obj = json_load_zip(fp=f)

详情:

它的工作原理是利用

codec._StreamWriter

作为中介,直接从字符串输入写入类似字节的 IO。这避免了无法直接转储到 zip 文件的原因 - 因为

json.dump
写入 unicode,而不是
ZipFile
所需的字节。
实施细节:

我已将 zip 中的 json 文件命名为

"data"

。这是因为对于我的实现,我只需要压缩单个 json 文件,并且文件的名称与我的目的无关。随心所欲地编辑!

    

© www.soinside.com 2019 - 2024. All rights reserved.