Python 如何仅提取.tar.gz成员的文件?
我的目标是解压Python 如何仅提取.tar.gz成员的文件?,python,python-3.x,tar,Python,Python 3.x,Tar,我的目标是解压.tar.gz文件,而不是解压指向该文件的子目录 我的代码基于此,只是没有解包.zip,而是解包.tar.gz文件 我问这个问题是因为我得到的错误非常模糊,没有在我的代码中识别问题: import os import shutil import tarfile with tarfile.open('RTLog_20150425T152948.gz', 'r:gz') as tar: for member in tar.getmembers(): filen
.tar.gz
文件,而不是解压指向该文件的子目录
我的代码基于此,只是没有解包.zip
,而是解包.tar.gz
文件
我问这个问题是因为我得到的错误非常模糊,没有在我的代码中识别问题:
import os
import shutil
import tarfile
with tarfile.open('RTLog_20150425T152948.gz', 'r:gz') as tar:
for member in tar.getmembers():
filename = os.path.basename(member.name)
if not filename:
continue
# copy file (taken from zipfile's extract)
source = member
target = open(os.path.join(os.getcwd(), filename), "wb")
with source, target:
shutil.copyfileobj(source, target)
如您所见,我从链接问题复制了代码,并尝试将其更改为处理.tar.gz成员而不是.zip成员。运行代码时,我得到以下错误:
Traceback (most recent call last):
File "C:\Users\dzhao\Desktop\123456\444444\blah.py", line 27, in <module>
with source, target:
AttributeError: __exit__
但这会在找不到文件时引发错误,这是可以理解的
我不明白什么?这段代码对我有用:
import os
import shutil
import tarfile
with tarfile.open(fname, "r|*") as tar:
counter = 0
for member in tar:
if member.isfile():
filename = os.path.basename(member.name)
if filename != "myfile": # do your check
continue
with open("output.file", "wb") as output:
shutil.copyfileobj(tar.fileobj, output, member.size)
break # got our file
counter += 1
if counter % 1000 == 0:
tar.members = [] # free ram... yes we have to do this manually
但是您的问题可能不是提取,而是您的文件确实不是.tar.gz,而只是一个.gz文件
编辑:也是因为python试图调用成员对象的函数(wich不存在),所以在with行中出现错误。我知道我的文件肯定是a.tar.gz。当我删除带有源代码和目标代码的
行时,我最初的恐惧是正确的。似乎我的源不是一个类似文件的对象。阅读完tar.fileobj
的功能后,我将尝试您的代码。修复方法是将源代码更改为tar.fileobj
。有趣的是,当我在tar文档页面上使用ctrl+f时,它并不是一个函数。所以它一定是一个变量。但是重要的是,tar.fileobj
是一个类似文件的对象,所以现在我的代码工作了=)谢谢!不客气。如果您处理的是大文件(100MB),我强烈建议包括免费的ram行。文档中没有提到这一点,但如果您的脚本突然失败,并且ram使用率非常高,这会让您大吃一惊。
import os
import shutil
import tarfile
with tarfile.open(fname, "r|*") as tar:
counter = 0
for member in tar:
if member.isfile():
filename = os.path.basename(member.name)
if filename != "myfile": # do your check
continue
with open("output.file", "wb") as output:
shutil.copyfileobj(tar.fileobj, output, member.size)
break # got our file
counter += 1
if counter % 1000 == 0:
tar.members = [] # free ram... yes we have to do this manually