ich habe einen Mikroservice gebaut, der via HTTP (POST) verschieden große Daten entgegen nimmt (Max. 100 MB). Diese Daten werden in der Applikation mit einer ID versehen, und anschließend mittels gzip komprimiert und einem stinknormalen Tararchiv angefügt, das bei `with gzip.open('file.gz', mode='wb')` entstehende, temporär erstellte File wird anschließend von der Platte gelöscht. Das Tar selbst ist nicht komprimiert, und beinhaltet somit n-verschiedene .gz-Dateien. An diese Vorgabe muss ich mich aufgrund anderer Services die auf diese Archive zugreifen, halten.
Nun dachte ich mir, dass man diesen ganzen Vorgang evtl. abkürzen kann, in dem man den Datenstrom entgegen nimmt, komprimiert, und dem Tararchiv anfügt, ohne eine temporäre Datei auf Platte schreiben und anschließend löschen zu müssen. Leider komme ich mit meinem Versuch nicht weiter:
Code: Alles auswählen
def append_to_tar(data):
buffer = io.BytesIO()
buffer.write(data)
buffer.seek(0)
with gzip.GzipFile(fileobj=buffer, mode='wb') as compressed_data_stream:
with tarfile.open('foo.tar', mode='a') as fd:
tarinfo = tarfile.TarInfo(name="bar.gz")
tarinfo.size = len(buffer.getbuffer())
fd.addfile(tarinfo=tarinfo, fileobj=compressed_data_stream)
if __name__ == '__main__':
sample_byte_stream = b"Hallo bla, bla blabla bla."
append_to_tar(sample_byte_stream)
Code: Alles auswählen
Traceback (most recent call last):
File "/app/test.py", line 48, in <module>
append_to_tar(sample_byte_stream)
File "app/test.py", line 43, in append_to_tar
fd.addfile(tarinfo=tarinfo, fileobj=compressed_data_stream)
File "/usr/lib/python3.6/tarfile.py", line 1977, in addfile
copyfileobj(fileobj, self.fileobj, tarinfo.size, bufsize=bufsize)
File "/usr/lib/python3.6/tarfile.py", line 254, in copyfileobj
buf = src.read(remainder)
File "/usr/lib/python3.6/gzip.py", line 275, in read
raise OSError(errno.EBADF, "read() on write-only GzipFile object")
OSError: [Errno 9] read() on write-only GzipFile object
Process finished with exit code 1