如何上下文管理多个 zip 文件的 BytesIO?

How to context manage BytesIO for multiple zip files?

我正在尝试在创建多个 zip 文件时对 BytesIO 流使用上下文管理器。在写入第一个 zip 文件后,我找不到 "reset" BytesIO 对象的方法,因此我可以使用相同的 BytesIO 对象来创建下一个 zip 文件。在将第二个 zip 文件写入磁盘后尝试打开它时,我总是遇到 "Can not open file ... as archive" 错误。第一个 zip 文件打开就好了。我已经搜索过,但找不到解决方案。将模式从写入更改为追加也无济于事。当然,我可以重新初始化为一个新的 BytesIO 对象,但这会破坏上下文管理器。以下是我认为应该有效的代码。我在 Windows 10.

上使用 Anaconda Python 3.6.6
import io
import os
import zipfile

with io.BytesIO() as bytes_io:
    with zipfile.ZipFile(bytes_io, mode='w') as zf:
        filecount = 0
        for item in os.scandir(r'C:\Users\stephen\Documents'):
            if not item.is_dir():
                zf.write(item.path, item.name)
                filecount += 1
                if filecount % 3 == 0:
                    with open(r'C:\Users\stephen\Documents\' + str(filecount // 3) + '.zip', 'wb') as f:
                        f.write(bytes_io.getvalue())
                    bytes_io.seek(0)
                    bytes_io.truncate()

您可以重复使用同一个 BytesIO 对象,但您应该为每个要创建的 zip 文件创建一个新的 ZipFile 对象:

with io.BytesIO() as bytes_io:
    filecount = 0
    for item in os.scandir(r'C:\Users\stephen\Documents'):
        if not item.is_dir():
            with zipfile.ZipFile(bytes_io, mode='w') as zf:
                zf.write(item.path, item.name)
            filecount += 1
            if filecount % 3 == 0:
                with open(r'C:\Users\stephen\Documents\' + str(filecount // 3) + '.zip', 'wb') as f:
                    f.write(bytes_io.getvalue())
                bytes_io.seek(0)
                bytes_io.truncate()