Как распаковать.tar.bz2 в памяти с питоном
Как распаковать файл *.bz2 в память с помощью python? Файл bz2 происходит из файла csv.
Я использую код ниже, чтобы распаковать его в памяти, он работает, но он приносит некоторые грязные данные, такие как имя файла csv и имя автора, есть ли другой лучший способ справиться с этим?
#!/usr/bin/python
# -*- coding: utf-8 -*-
import StringIO
import bz2
with open("/app/tmp/res_test.tar.bz2", "rb") as f:
content = f.read()
compressedFile = StringIO.StringIO(content)
decompressedFile = bz2.decompress(compressedFile.buf)
compressedFile.seek(0)
with open("/app/tmp/decompress_test", 'w') as outfile:
outfile.write(decompressedFile)
Я нашел этот вопрос, это в gzip, однако мои данные в формате bz2, я пытаюсь сделать, как указано в нем, но кажется, что bz2 не может обработать это таким образом.
Редактировать:
Независимо от ответа @metatoaster или приведенного выше кода, оба они внесут более грязные данные в окончательный распакованный файл. Например: мои исходные данные прикреплены ниже и в формате csv с именем res_test.csv:
Затем я перехожу в каталог, в котором находится файл, и сжимаю его tar -cjf res_test.tar.bz2 res_test.csv
и получить сжатый файл res_test.tar.bz2, этот файл может имитировать данные bz2, которые я получу из Интернета, и я хочу распаковать их в памяти без предварительного кэширования на диск, но я получаю данные ниже и содержит слишком много грязные данные:
Данные все еще там, но погружены в шум, возможно ли распаковывать их в чистые данные, точно так же, как исходные данные, вместо распаковки и извлекать реальные данные из слишком большого количества шума?
1 ответ
Для общей декомпрессии bz2, BZ2File
класс может быть использован.
from bz2 import BZ2File
with BZ2File("/app/tmp/res_test.tar.bz2") as f:
content = f.read()
content
должен содержать распакованное содержимое файла.
Однако, учитывая, что это tar
файл (архивный файл, который обычно извлекается на диск как каталог файлов), tarfile
модуль может быть использован вместо него, и он имеет расширенные флаги режима для обработки bz2. Предполагая, что целевой файл содержит res_test.csv
можно использовать следующее
tf = tarfile.open('/app/tmp/res_test.tar.bz2', 'r:bz2')
csvfile = tf.extractfile('res_test.csv').read()
r:bz2
flag открывает архив tar таким образом, что позволяет искать в обратном направлении, что важно в качестве альтернативного метода r|bz2
делает нецелесообразным вызывать извлечение файлов из членов, которые он возвращает extractfile
, Вторая строка просто вызывает extractfile
вернуть содержимое 'res_test.csv'
из архива в виде строки.
Прозрачный открытый режим ('r:*'
), как правило, рекомендуется, однако, если входной tar-файл сжат с использованием gzip, сбоев не возникнет.
Естественно, что tarfile
модуль имеет более низкий уровень open
метод, который может использоваться на объектах произвольного потока. Если файл уже был открыт с помощью BZ2File
уже это тоже можно использовать
with BZ2File("/app/tmp/res_test.tar.bz2") as f:
tf = tarfile.open(fileobj=f, mode='r:')
csvfile = tf.extractfile('res_test.csv').read()