爬蟲(四十九)通用標準庫 tarfile(四十)

既然有壓縮模塊zipfile,那有一個歸檔模塊tarfile也是很天然的。tarfile模塊用於解包和打包文件,包括被gzipbz2lzma壓縮後的打包文件。若是是.zip類型的文件,建議使用zipfile模塊,更高級的功能請使用shutil模塊。python

定義的類和異常

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)windows

返回一個TarFile類型的對象。本質上就是打開一個文件對象。Python隨處可見這種文件對象類型的設計,你很容易就明白,不是嗎?安全

name是文件名或路徑。微信

bufsize用於指定數據塊的大小,默認爲20*512字節。app

mode是打開模式,一個相似filemode[:compression]格式的字符串,能夠有下表所示的組合,默認爲「r」。ui

若是當前模式不能正常打開文件用於讀取,將拋出ReadError異常,這種狀況下,請使用「r」模式。若是指定的壓縮方式不支持,將拋出CompressionError異常。編碼

w:gz,r:gz,w:bz2,r:bz2,x:gz,x:bz2模式下,tarfile.open()方法額外接受一個壓縮等級參數compresslevel,默認值爲9。spa

class tarfile.TarFile.net

用於讀寫tarfile文件的類。不要直接使用這個類,請使用tarfile.open()方法。命令行

tarfile.is_tarfile(name)

判斷一個文件是否打包文件類型。

exception tarfile.TarError

tarfile模塊全部異常類的基類

exception tarfile.ReadError

讀異常

exception tarfile.CompressionError

壓縮異常

exception tarfile.StreamError

流異常

exception tarfile.ExtractError

解壓異常

exception tarfile.HeaderError

頭部異常

tarfile.ENCODING

tarfile的編碼方式。在windows系統中,字符編碼爲utf-8。在其它系統中爲sys.getfilesystemencoding()方法的返回值。

TarFile對象

該對象提供了訪問打包文件的接口。打包文件本質上是數據塊的序列。包中的每一個文件成員都是由頭部塊和數據塊組成的。在包中,文件有可能重複。包裏的每一個文件都是一個TarInfo對象。因此遍歷一個TarFile對象,就是遍歷一個TarInfo對象的集合,這一點要搞清楚。

TarFile對象一樣可使用with語句進行上下文管理。

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=0)

TarFile類

TarFile.getmember(name)

獲取某個成員的信息

TarFile.getmembers()

獲取包內全部成員的信息

TarFile.getnames()

獲取包內全部成員的名字

TarFile.list(verbose=True, *, members=None)

列表顯示包內成員信息

TarFile.next()

顯示下一個文件的信息

TarFile.extractall(path=".", members=None, *, numeric_owner=False)

解包全部文件到當前目錄,或path指定的目錄。警告:解包文件以前必定要確保安全,防止覆蓋本地或上級目錄等惡意行爲。

TarFile.extract(member, path="", set_attrs=True, *, numeric_owner=False)

解包指定文件

TarFile.extractfile(member)

同上

TarFile.add(name, arcname=None, recursive=True, exclude=None, *, filter=None)

將指定文件加入包內。arcname參數用於變換路徑和文件名。默認狀況下,文件夾會被遞歸的加入包內,除非recursive參數設爲Falsefilter參數指向一個方法,該方法用來過濾哪些文件不會被打入包內,不被打包的就返回個None,會的就返回tarinfo自己,該方法爲3.2版本新增,同時廢棄原有的exclude方法。

TarFile.addfile(tarinfo, fileobj=None)

將一個tarinfo對象關聯的文件加入包內。

TarFile.close()

關閉TarFile文件。在「w」模式下,會在文件末尾添加量個zero塊。

使用範例:

>>> import os
>>> os.getcwd()
'C:\\Python36'
>>> os.chdir("d:\\test")
>>> os.getcwd()
'd:\\test'
>>> os.listdir()
['1.txt', '2.txt', 'test.py', 'test.txt']
>>> import tarfile
>>> tar = tarfile.open("test.tar.gz", "w:gz")
>>> tar.add("1.txt")
>>> tar.add("2.txt")
>>> tar.add("test.txt")
>>> tar.add("test.py")
>>> tar.close()
>>> os.listdir()
['1.txt', '2.txt', 'test.py', 'test.tar.gz', 'test.txt']
>>> tar = tarfile.open("test.tar.gz",)
>>> tar.getmembers()
[<TarInfo '1.txt' at 0x2a7ae58>, <TarInfo '2.txt' at 0x2df6368>, <TarInfo 'test.txt' at 0x2df6430>, <TarInfo 'test.py' at 0x2df64f8>]
>>> tar.getnames()
['1.txt', '2.txt', 'test.txt', 'test.py']
>>> tar.list()
?rw-rw-rw- 0/0 9 2017-05-17 22:05:31 1.txt
?rw-rw-rw- 0/0 9 2017-05-17 22:05:31 2.txt
?rw-rw-rw- 0/0 25 2017-05-16 11:54:45 test.txt
?rw-rw-rw- 0/0 96 2017-05-18 08:50:59 test.py
>>> tar.getmember("1.txt")
<TarInfo '1.txt' at 0x2a7ae58>

TarInfo對象

一個TarInfo對象表明TarFile裏的一個成員。除了保存全部文件必需的屬性(例如文件類型、大小、時間、權限、擁有者等等),它還提供了不少有用的方法,用來判斷它的類型。可是它不包含文件的具體數據內容。

TarFile對象的getmember(),getmembers()gettarinfo()會返回TarInfo對象。

命令行界面

tarfile模塊還提供一種命令行界面下的交互模式。該功能屬於Python3.4版本新增。

若是你想建立一個包,在-c參數後指定包名稱,而後列出打包的文件,以下所示(-m參數是指定使用的模塊):

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

也能夠指定一個文件夾:

$ python -m tarfile -c monty.tar life-of-brian_1979/

若是想要解包到當前目錄,請使用-e參數:

$ python -m tarfile -e monty.tar

固然,也能夠解包到指定目錄:

$ python -m tarfile -e monty.tar  other-dir/

想查看包內文件列表,使用-l參數:

$ python -m tarfile -l monty.tar

一些例子

1.解包到當前目錄

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()

2.指定包內某一類型文件被解包

import os
import tarfile

def py_files(members):
for tarinfo in members:
if os.path.splitext(tarinfo.name)[1] == ".py":
yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

3.根據文件名列表,建立不壓縮的包

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
tar.add(name)
tar.close()

使用with語句的寫法:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
for name in ["foo", "bar", "quux"]:
tar.add(name)

4.解包使用gzip壓縮的包文件,並顯示部分信息。

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
for tarinfo in tar:
print(tarinfo.name, "is", tarinfo.size, "bytes in size and is", end="")
if tarinfo.isreg():
print("a regular file.")
elif tarinfo.isdir():
print("a directory.")
else:
print("something else.")
tar.close()

5.往包內添加文件,並使用filter參數修改文件信息。

import tarfile
def reset(tarinfo):
tarinfo.uid = tarinfo.gid = 0
tarinfo.uname = tarinfo.gname = "root"
return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

6.壓縮並打包文件夾下的全部文件及目錄

import os  
import tarfile

tar = tarfile.open('test.tar','w:gz')
for root ,dir,files in os.walk(os.getcwd()):
for file in files:
fullpath = os.path.join(root,file)
tar.add(fullpath)

總結

tarfile模塊看似複雜,其實也很簡單,只須要掌握下面幾個重點方法就能夠了:

請繼續關注我


記得點贊加關注哦,記得加雞腿啊

本文分享自微信公衆號 - 人生代碼(lijinwen1996329ken)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索