Skip to main content

即时创建 zip 文件

项目描述

AioZipStream

这是ZipStream的一个分支。用于流式传输动态创建的 ZIP 文件的简单 python 库,无需使用任何临时文件。

  • 无临时文件,数据直接流式传输
  • 支持的deflate压缩方式
  • 内存占用小,使用yield语句实现straming
  • 存档结构是动态创建的,所有数据都可以在流期间创建
  • 包含在存档中的文件可以使用 Python 生成器即时生成
  • 提供异步 AioZipStream 和经典 ZipStream
  • Zip32 格式兼容文件
  • 独立于 python 的标准 ZipFile 实现
  • 几乎没有依赖关系:仅aiofiles在某些情况下(有关详细信息,请参阅 AioZipStream 部分)
  • Zip64 支持也计划在未来(遥远的未来,因为我从来没有达到 4GB 文件大小限制;-))

所需的 Python 版本:

ZipStream与Python 2.7兼容。

AioZipStream需要Python 3.6。对于早期版本AioZipStream,无法导入。

用法:

要归档的文件列表存储为字典列表。为什么要听写?因为每个文件都可能有额外的参数,未来计划更多的参数。

要归档的文件示例列表:

files = [
         # file /tmp/file.dat will be added to archive under `file.dat` name.
         {'file':'/tmp/file.dat'},

         # same file as previous under own name: `completly_different.foo`
         # and will be compressed using `deflate` compression method
         {'file':'/tmp/file.dat',
          'name':'completly_different.foo',
          'compression':'deflate'}
        ]

是时候流式传输/存档了:

zs = ZipStream(files)
with open("example.zip", "wb") as fout:
    for data in zs.stream():
        fout.write(data)

任何可迭代的二进制数据源都可以用来代替常规文件。使用生成器作为文件的输入必须用stream字段而不是表示,还需要file附加参数。name

def source_of_bytes():
    yield b"123456789"
    yield b"abcdefgh"
    yield b"I am a binary data"

files = [....
         # file will be generated dynamically under name my_data.bin
         {'stream': source_of_bytes(), 'name': 'my_data.bin'},
        ]

请记住,数据应该以合理大小的块提供,因为在使用流的情况下,ZipStream类无法自行拆分数据。

要流式传输的文件列表也可以在流式传输期间动态生成:

import os
from zipstream import ZipStream

def files_to_stream_with_foo_in_name(dirname):
    # all files from selected firectory
    for f in os.listdir(dirname):
        fp = os.path.join(dirname, f)
        if os.path.isfile(fp):
            yield {'file': fp,
                   'name': "foo_" + os.path.basename(fp)}
    # and our generator too
    yield {'stream': source_of_bytes(),
           'name': 'my_data.bin',
           'compression': 'deflate'}

zs = ZipStream(files_to_stream_with_foo_in_name('\tmp\some-files'))

异步 AioZipStream

:warning:要使用异步 AioZipStream 至少需要 Python 3.6 版本。AioZipStream 使用异步生成器语法,wchich 从 3.6 版本开始可用。

要使用本地文件aiofiles,需要附加库。如果您计划仅流式传输动态生成的内容,则aiofiles不需要。

有关. _ _aiofiles

异步 zip 流的示例

任何用于动态创建数据的生成器都必须定义为async:

async def content_generator():
    yield b'foo baz'
    asyncio.sleep(0.1) # we simulate little slow source of data
    data = await remote_data_source()
    yield bytes(data, 'utf-8') # always remember to yield binary data
    asyncio.sleep(0.5)
    yield b"the end"

zip流也必须在async函数内部。注意使用aiofiles.open而不是open,它是异步的,不会在磁盘访问期间阻塞事件循环。

from zipstream import AioZipStream

async def zip_async(zipname, files):
    aiozip = AioZipStream(files, chunksize=32768)
    async with aiofiles.open(zipname, mode='wb') as z:
        async for chunk in aiozip.stream():
            await z.write(chunk)

这是要发送的文件列表:

files = [
    {'file': '/tmp/car.jpeg'},
    {'file': '/tmp/aaa.mp3', 'name': 'music.mp3'},
    {'stream': content_generator(),
     'name': 'random_stuff.txt'}
]

启动 asyncio 循环并将结果流式传输到文件:

loop = asyncio.get_event_loop()
loop.run_until_complete(zip_async('example.zip', files))
loop.stop()

例子

examples有关ZipStream 和 AioZipStream 的完整代码和工作示例,请参见目录。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

aiozipstream-0.4.tar.gz (7.8 kB 查看哈希)

已上传 source

内置分布

aiozipstream-0.4-py2.py3-none-any.whl (8.6 kB 查看哈希)

已上传 py2 py3