Bytestream komprimieren und tar anhängen
Verfasst: Freitag 18. Mai 2018, 09:51
Hallo,
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:
Die Fehlermeldung scheint erstmal plausibel, nur habe ich keine funktionierende Lösung wie ich den komprimierten Stream als Fileobjekt kopieren, in 'rb' öffnen und anschließend dem Tar anfügen kann. Ist das überhaupt irgendwie sinnvoll / möglich den Stream direkt in das Tar zu schubsen?
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