TarFile.extractall () работает нормально, но не создает никаких новых файлов или каталогов - PullRequest
0 голосов
/ 17 октября 2019

Версия: Python 2.7 ОС: MacOS Mojave IDE: Pycharm Community 2019.2

У меня проблемы с загрузкой файлов tar.gz из pypi.org/project и их разархивированием. Вариант использования для этого заключается в том, что мы не можем использовать какое-либо реальное управление пакетами, поэтому мы должны вручную помещать пакеты в нужные нам папки в локальные папки. Мое решение для этого состоит в том, чтобы прочитать файл требований и вытащить файлы tar.gz и .zip для указанных версий, а затем записать в локальные файлы.

У меня он работает для файлов ZIP, и он работаетименно так, как я этого хочу. Zip-файлы обрабатываются оператором elif, tar-файлы обрабатываются оператором if. По какой-то причине для ссылок на файлы tar, которые я передаю, каталоги не создаются, файлы не извлекаются.

Я сделал тест, указав путь к моей локальной копии файла tar прямо в этой строке tarData = tarfile.open(fileobj=zipData, mode='r:*') вместо zipData и это сработало, так что я думаю, что это как-то связано с форматом, в котором файл загружается или обрабатывается в StringIO, но я не получаю никаких исключений, поэтому у меня нет возможности сузитьв чем проблема.

Ниже приведен фрагмент кода, который я использую для распаковки этих файлов.

import os
import bs4 as bs
import urllib2
import re
from StringIO import StringIO
import zipfile
import tarfile
import requests


def install_packages_locally(compressed_link, directory):
    file_name = '_'.join(compressed_link.split('/')[-1].split('-')[:-1])
    file_ext = compressed_link.split('-')[-1]
    response = requests.get(compressed_link, stream=True)

    if file_name in os.listdir(directory):
        print('Skipping %s' % file_name)
        return True

    zipData = StringIO()

    if file_ext.endswith('.tar.gz'):
        zipData.write(response.raw.read())
        print('writing %s to %s' % (file_name, directory))
        tarData = tarfile.open(fileobj=zipData, mode='r:*')
        tarData.extractall(path=directory)
        tarData.close()
        zipData.close()
        return True

    elif file_ext.endswith('.zip'):
        zipData.write(response.content)
        print('writing %s to %s' % (file_name, directory))
        unzipData = zipfile.ZipFile(zipData)
        unzipData.extractall(path=directory)
        unzipData.close()
        zipData.close()
        return True

1 Ответ

0 голосов
/ 17 октября 2019

Ответили здесь: https://www.reddit.com/r/learnpython/comments/dix37i/tarfileextractall_processes_fine_but_doesnt/f3zq1j4?utm_source=share&utm_medium=web2x

Я нашел другой пример, который включал вызов BytesIO.seek (0) для сброса указателя файла на начало:

Если fileobjуказано, используется как альтернатива файловому объекту, открытому в двоичном режиме для имени. Предполагается, что он находится в позиции 0.

https://docs.python.org/3/library/tarfile.html

Поэтому вы должны добавить вызов zipData.seek (0) перед вызовом tarfile.open.

...