Извлечение.ppm.bz2 из пользовательского пути в пользовательский путь

Как видно из названия, у меня есть несколько папок, несколько файлов.ppm.bz2, и я хочу извлечь их именно там, где они используют Python.

Структура каталогов изображения

Я перехожу в папки, как это:

 import tarfile
 import os
 path = '/Users/ankitkumar/Downloads/colorferet/dvd1/data/images/'
 folders = os.listdir(path)
 for folder in folders:  #the folders starting like 00001
     if not folder.startswith("0"):
         pass
     path2 = path + folder
     zips = os.listdir(path2)
     for zip in zips:
         if not zip.startswith("0"):
             pass
         path3 = path2+"/"+zip

         fh = tarfile.open(path3, 'r:bz2')
         outpath = path2+"/"
         fh.extractall(outpath)
         fh.close

`

тогда я получаю эту ошибку

Traceback (most recent call last):
  File "ZIP.py", line 16, in <module>
    fh = tarfile.open(path3, 'r:bz2')
  File "/anaconda2/lib/python2.7/tarfile.py", line 1693, in open
    return func(name, filemode, fileobj, **kwargs)
  File "/anaconda2/lib/python2.7/tarfile.py", line 1778, in bz2open
    t = cls.taropen(name, mode, fileobj, **kwargs)
  File "/anaconda2/lib/python2.7/tarfile.py", line 1723, in taropen
    return cls(name, mode, fileobj, **kwargs)
  File "/anaconda2/lib/python2.7/tarfile.py", line 1587, in __init__
    self.firstmember = self.next()
  File "/anaconda2/lib/python2.7/tarfile.py", line 2370, in next
    raise ReadError(str(e))
tarfile.ReadError: invalid header

`

1 ответ

Решение

Модуль tarfile предназначен для файлов tar, в том числе tar.bz2, если ваш файл не tar ты должен использовать bz2 модуль напрямую.

Кроме того, попробуйте использовать os.walk вместо нескольких listdir как это может пересечь дерево

import os
import bz2
import shutil

for path, dirs, files in os.walk(path):
    for filename in files:
        basename, ext = os.path.splitext(filename)
        if ext.lower() != '.bz2':
            continue
        fullname = os.path.join(path, filename)
        newname = os.path.join(path, basename)
        with bz2.open(fullname) as fh, open(newname, 'wb') as fw:
            shutil.copyfileobj(fh, fw)

Это распакует все .bz2 файлы во всех подпапках, там же они и есть. Все остальные файлы останутся прежними. Если несжатый файл уже существует, он будет перезаписан.

Пожалуйста, сделайте резервную копию ваших данных перед запуском разрушительного кода

Другие вопросы по тегам