Прочтите файл .tar.gz в Python

У меня есть текстовый файл размером 25 ГБ. поэтому я сжал его до tar.gz, и он стал 450 МБ. теперь я хочу прочитать этот файл с python и обработать текстовые данные. Для этого я назвал question. но в моем случае код не работает. код выглядит следующим образом:

import tarfile
import numpy as np 

tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
     f=tar.extractfile(member)
     content = f.read()
     Data = np.loadtxt(content)

ошибка такова:

Traceback (most recent call last):
  File "dataExtPlot.py", line 21, in <module>
    content = f.read()
AttributeError: 'NoneType' object has no attribute 'read'

также, есть ли какой-либо другой метод для выполнения этой задачи?

Ответ 1

docs сообщают нам, что None возвращается exfilefile(), если этот элемент не является обычным файлом или ссылкой.

Одним из возможных решений является пропустить результаты None:

tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
     f = tar.extractfile(member)
     if f is not None:
         content = f.read()

Ответ 2

tarfile.extractfile() может возвращать None, если элемент не является ни файлом, ни ссылкой. Например, ваш архив tar может содержать каталоги или файлы устройств. Исправить:

import tarfile
import numpy as np 

tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
     f = tar.extractfile(member)
     if f:
         content = f.read()
         Data = np.loadtxt(content)

Ответ 3

Вы можете попробовать этот

t = tarfile.open("filename.gz", "r")
for filename in t.getnames():
    try:
        f = t.extractfile(filename)
        Data = f.read()
        print filename, ':', Data
    except :
        print 'ERROR: Did not find %s in tar archive' % filename

Ответ 4

Вы не можете "читать" содержимое некоторых специальных файлов, таких как ссылки, но tar поддерживает их, а tarfile будет извлекать их в порядке. Когда tarfile извлекает их, он не возвращает файл-подобный объект, кроме None. И вы получаете сообщение об ошибке, потому что ваш архив содержит такой специальный файл.

Один из подходов состоит в том, чтобы определить тип записи в tarball, который вы обрабатываете, прежде чем извлекать его: с помощью этой информации вы можете решить, можете ли вы "прочитать" файл. Вы можете достичь этого, вызвав tarfile.getmembers() return tarfile.TarInfo, который содержит подробную информацию о типе файла, содержащегося в tarball.

В классе tarfile.TarInfo есть все атрибуты и методы, необходимые для определения типа члена tar, такого как isfile() или isdir() или tinfo.islnk() или tinfo.issym(), а затем, соответственно, решить, что делать с каждым членом (извлечение или нет и т.д.).

Например, я использую их для проверки типа файла в этот исправленный tarfile, чтобы пропустить извлечение специальных файлов и ссылок на процесс особым образом

for tinfo in tar.getmembers():
    is_special = not (tinfo.isfile() or tinfo.isdir()
                      or tinfo.islnk() or tinfo.issym())
...