I am trying to use a context manager for a BytesIO stream while creating multiple zip files. I can find no way to "reset" the BytesIO object after the first zip file is written, so I can use the same BytesIO object to create the next zip file. I always get a "Can not open file ... as archive" error when trying to open the second zip file after it is written to disk. First zip file opens just fine. I have searched and cannot find a solution. Changing modes from write to append didn't help either. I can, of course, reinitialize to a new BytesIO object, but that defeats the context manager. Below is the code I thought should work. I'm using Anaconda Python 3.6.6 on Windows 10.
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()
You can reuse the same BytesIO
object, but you should create a new ZipFile
object for every zip file you want to create:
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()