Python TarFile.extractall()处理得很好,但不';不要创建任何新的文件或目录

Python TarFile.extractall()处理得很好,但不';不要创建任何新的文件或目录,python,python-2.7,compression,tar,stringio,Python,Python 2.7,Compression,Tar,Stringio,版本:Python 2.7 OS:MacOS Mojave IDE:Pycharm社区2019.2 从pypi.org/project下载tar.gz文件并解压缩时遇到问题。这个用例是我们不能使用任何实际的包管理,所以我们必须手动将包放在本地文件夹中需要它们的地方。我的解决方案是读取一个需求文件,提取给定版本的tar.gz和.zip文件,然后写入本地文件 我已经让它为zip文件工作,它正是我想要的工作方式。Zip文件由'elif'语句处理,tar文件由'if'语句处理。出于某种原因,对于我传入的

版本:Python 2.7 OS:MacOS Mojave IDE:Pycharm社区2019.2

pypi.org/project
下载tar.gz文件并解压缩时遇到问题。这个用例是我们不能使用任何实际的包管理,所以我们必须手动将包放在本地文件夹中需要它们的地方。我的解决方案是读取一个需求文件,提取给定版本的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
答复如下:

我发现了另一个示例,其中包括对BytesIO.seek(0)的调用 将文件指针重置为开始位置:

如果指定了fileobj,则将其用作文件对象的替代对象 以二进制模式打开名称。它应该位于位置0

因此,您应该在调用之前添加对zipData.seek(0)的调用 tarfile.open