implements class :py:class:`ZipStream` which is a subclass of ZipFile that can
read from non-seekable input streams and write to non-seekable output streams.
+Use as follows::
+
+ from pyi2ncommon.zip_stream import ZipStream
+ with ZipStream(output_stream, 'w') as zip:
+ info = zip.create_zipinfo(big_file)
+ with open(big_file, 'rb') as input_stream:
+ zip.write_stream(input_stream, info)
+
.. codeauthor:: Intra2net AG <info@intra2net>
"""
from zipfile35 import *
from type_helpers import isstr
+
+# copied from zipfile.py
ZIP64_LIMIT = (1 << 31) - 1
+
def _get_compressor(compress_type):
"""Copied fomr zipfile.py in py3.5 (cannot legally import)"""
if compress_type == ZIP_DEFLATED:
else:
return None
+
class ZipStream(ZipFile):
"""Subclass of ZipFile that supports non-seekable input and output"""
def create_zipinfo(self, filename, arcname=None):
"""
Create ZipInfo for given file
-
+
Optionally set arcname as name of file inside archive.
Adapted from zipfile.py in (ZipInfo.from_file in py3.6, ZipFile.write
def write_stream(self, src, zinfo):
"""
Add data from byte stream stream src to archive with info in ZipInfo.
-
+
Param zinfo must be a ZipInfo, created e.g. with
:py:meth:`ZipStream.create_zipinfo`
else:
return self._write_stream_35(src, zinfo)
-
def _write_stream_35(self, src, zinfo):
"""Implementation of _write_stream based on ZipFile.write (py 3.5)"""
if not self.fp:
with self.open(zinfo, 'w') as dest:
shutil.copyfileobj(src, dest, 1024*8)
-
-
-if __name__ == '__main__':
- import gzip
-
- print('[stderr] Py version is {}, ZipFile is {}, Encoding is {}, is a tty: {}'
- .format(sys.version, ZipFile, sys.stdout.encoding,
- sys.stdout.isatty()),
- file=sys.stderr)
-
- with ZipStream(sys.stdout.buffer, 'w', compression=ZIP_DEFLATED) as zip:
- for arg in sys.argv[1:]:
- basename = os.path.basename(arg)
- if arg.endswith('.gz'):
- print('[stderr] reading from compressed file {}'.format(arg),
- file=sys.stderr)
- info = zip.create_zipinfo(arg, basename[:-3])
- with gzip.open(arg, 'rb') as reader:
- zip.write_stream(reader, info)
- else:
- print('[stderr] reading from regular file {}'.format(arg),
- file=sys.stderr)
- info = zip.create_zipinfo(arg, basename)
- with open(arg, 'rb') as reader:
- zip.write_stream(reader, info)