tarfile.open(mode='w:gz'|'w|gz'|..., fileobj=StringIO()) fails.
sebastian.noack at googlemail.com
sebastian.noack at googlemail.com
Tue May 27 04:51:47 EDT 2008
I have written a FileWrapper class as workaround, which works for me
(see the code below). The FileWrapper object holds an internal file-
like object and maps its attributes, but prevents the user (in this
case tarfile) from closing the internal file, so I can still access
StringIO's content after closing the TarFile object.
But this should not be required to create in memory tar files. It is
definitely a bug, that TarFile closes external file objects passed to
tarfile.open, when closing the TarFile object. The code which opens a
file is also responsible for closing it.
Regards
Sebastian Noack
#
# File: StringIO-tarfile.py
#
#!/usr/bin/env python
from StringIO import StringIO
import tarfile
import sys
class FileWrapper(object):
def __init__(self, fileobj):
self.file = fileobj
self.closed = fileobj.closed
def __getattr__(self, name):
# Raise AttributeError, if it isn't a file attribute.
if name not in dir(file):
raise AttributeError(name)
# Get the attribute of the internal file object.
value = getattr(self.file, name)
# Raise a ValueError, if the attribute is callable (e.g. an instance
# method) and the FileWrapper is closed.
if callable(value) and self.closed:
raise ValueError('I/O operation on closed file')
return value
def close(self):
self.closed = True
def create_tar_file(filenames, fileobj, mode):
tar_file = tarfile.open(mode=mode, fileobj=fileobj)
for f in filenames:
tar_file.add(f)
tar_file.close()
if __name__ == '__main__':
files = sys.argv[1:]
modes = ['w%s%s' % (x, y) for x in (':', '|') for y in ('', 'gz',
'bz2')]
for mode in modes:
ext = mode.replace('w|', '-pipe.tar.').replace('w:',
'.tar.').rstrip('.')
# StringIO test.
stream = FileWrapper(StringIO())
create_tar_file(files, stream, mode)
fd = open('StringIO%s' % ext, 'w')
fd.write(stream.file.getvalue())
stream.file.close()
fd.close()
# file object test.
fd = open('file%s' % ext, 'w')
create_tar_file(files, fd, mode)
More information about the Python-list
mailing list