2016-05-27 6 views
11

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

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

Что-то вроде http://stackoverflow.com/q/33113600/ 1240268 –

+1

* Если элемент не указан выше, возвращается None. *, Член не является файлом или ссылкой. –

ответ

14

docs говорят нам, что Ни один не возвращается extractfile() если член является не обычный файл или ссылку.

Одним из возможных решений является перескочить 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() 
3

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) 
1

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

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 
+0

Спасибо за фрагмент кода. Вы читаете дважды, хотя - один раз при настройке переменной «data» и в следующий раз при печати. Можете ли вы изменить свой код, чтобы исправить это? –

+0

@SaurabhHirani Изменено. Спасибо за напоминания. – VICTOR

1

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

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

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

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

for tinfo in tar.getmembers(): 
    is_special = not (tinfo.isfile() or tinfo.isdir() 
         or tinfo.islnk() or tinfo.issym()) 
... 
Смежные вопросы