文章出處

Python中可以用于對文件和目錄進行操作的內置模塊包括:

模塊/函數名稱 功能描述
open()函數 文件讀取或寫入
os.path模塊 文件路徑操作
os模塊 文件和目錄簡單操作
zipfile模塊 文件壓縮
tarfile模塊 文件歸檔壓縮
shutil模塊 高級文件和目錄處理及歸檔壓縮
fileinput模塊 讀取一個或多個文件中的所有行
tempfile模塊 創建臨時文件和目錄

其中文件讀取或寫入已經在之前的文章中進行了描述,具體請參考這里 《Python之文件讀寫》。這里主要對其它幾個模塊進行下說明。

一、文件路徑操作(os.path模塊)


os.path模塊主要用于對文件路徑的操作,如:路徑分割和拼接、取文件相對路徑和絕對路徑、獲取文件路徑對應文件的時間屬性、判斷文件路徑對應文件的類型、判斷兩個路徑是否為同一個文件等。

1. 函數列表

# 返回指定文件的絕對路徑名
os.path.abspath(path)

# 將路徑名稱分割成兩部分(head, tail),tail是路徑名稱path中的最后一部分且不包含斜線(路徑風格符),head是tail之前的所有部分;如果path以斜線結尾則 tail為空字符串,如果path中沒有斜線則head為空字符串
os.path.split(path)

# 將路徑名稱分割成兩部分(root, ext), ext表示后綴名
os.path.splitext(path)  

# 返回path路徑名的基名稱,實際上就是os.path.split(path)函數返回值的第二個值
os.path.basename(path)  

# 返回path路徑名的目錄名稱,實際上就是os.path.split(path)函數返回值的第一個值
os.path.dirname(path)  

# 將一個或多個路徑中的非空值通過路徑分隔符拼接成一個新的路徑名稱,如果在拼接過程中遇到絕對路徑將會丟棄前面的部分并從該絕對路徑重新開始拼接
os.path.join(path, *paths)  

# 指定的文件路徑存在則返回Ture,否則返回False。如果是失效的鏈接文件則返回False
os.path.exists(path)  

# 返回該路徑對應文件的最近一次訪問時間的時間戳(秒),如果文件不存在或無法訪問,則引發OSError
os.path.getatime(path)  

# 返回該路徑對應文件的最后修改時間的時間戳(秒),如果文件不存在或無法訪問,則引發OSError
os.path.getmtime(path)  

# 返回該路徑對應文件的ctime,在某些系統上(如Unix上)是最后一次元數據更改時間,在其他系統上(如Windows)是路徑的創建時間;如果文件不存在或無法訪問,則引發OSError
os.path.getctime(path)  

# 返回指定路徑對應文件的字節大小
os.path.getsize(path)  

# 返回path相對于start的相對路徑
os.path.relpath(path, start=os.curdir)  

# 獲取path的真實、絕對路徑(可用于獲取軟鏈接文件指向的文件路徑)
os.path.realpath(path)  

# 判斷path是否是絕對路徑,是則返回True,否則返回False
os.path.isabs(path)  

# 判斷path是否是一個文件
os.path.isfile(path)  

# 判斷path是否是一個目錄
os.path.isdir(path) 

# 判斷path是否是一個鏈接
os.path.islink(path)  

# 判斷path是否是一個掛載點
os.path.ismount(path)  

# 判斷path1和path2是否為同一個文件
os.path.samefile(path1, path2)  

注意: os.path.basename(path)函數與Unix 中的basename程序的不同之處在于,當path以路徑分隔符結尾時(如'/usr/local/'),basename(path)返回值為空字符串(''),而basename程序返回值為倒數第二個路徑分隔符之后的目錄名稱('local')

2. 實例

>>> import os
>>> 
>>> os.path.abspath('test.sh')
'/root/test.sh'

>>> os.path.split('/root/test.sh')
('/root', 'test.sh')
>>> os.path.split('/usr/local')
('/usr', 'local')
>>> os.path.split('/usr/local/')
('/usr/local', '')
>>> os.path.split('test.sh')
('', 'test.sh')

>>> os.path.basename('/root/test.sh')
'test.sh'
>>> os.path.dirname('/root/test.sh')
'/root'

>>> os.path.splitext('test.sh')
('test', '.sh')
>>> os.path.splitext('/root/test.sh')
('/root/test', '.sh')
>>> os.path.splitext('/usrl/local')
('/usrl/local', '')

>>> os.path.join('/root')
'/root'
>>> os.path.join('/root', '1', '', '2', ' ', '3' )
'/root/1/2/ /3'
>>> os.path.join('/root', '/usr/local', 'test.sh')
'/usr/local/test.sh'
>>> os.path.join('/root', '/usr/local', '1', '')
'/usr/local/1/'

>>> os.path.exists('/root/test.sh')
True
>>> os.path.exists('/root/test.txt')
False
>>> os.path.exists('/etc/rc0.d')
True

>>> os.path.getatime('/etc/my.cnf')
1483433424.62325
>>> os.path.getmtime('/etc/my.cnf')
1472825145.4308648
>>> os.path.getctime('/etc/my.cnf')
1472825145.432865

>>> os.path.relpath('/etc/my.cnf')
'../etc/my.cnf'
>>> os.path.relpath('/etc/my.cnf', start='/etc')
'my.cnf

>>> os.path.realpath('/etc/rc0.d')
'/etc/rc.d/rc0.d'
>>> os.path.realpath('test.sh')
'/root/test.sh'

>>> os.system('ls -l /etc/my.cnf')
-rw-r--r-- 1 root root 597 Sep  2 22:05 /etc/my.cnf
>>> os.path.getsize('/etc/my.cnf')
597

>>> os.path.isabs('/etc/my.cnf')
True
>>> os.path.isabs('my.cnf')
False
>>> os.path.isfile('/etc/my.cnf')
True
>>> os.path.isdir('/etc/my.cnf')
False
>>> os.path.islink('/etc/my.cnf')
False
>>> os.path.islink('/etc/rc0.d')
True
>>> os.path.islink('/etc/rc0.d/')
False
>>> os.path.isdir('/etc/rc0.d/')
True
>>> os.path.isdir('/etc/rc0.d')
True

>>> os.system('df -Th')
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/vda1      ext4       40G  8.7G   29G  24% /
devtmpfs       devtmpfs  3.9G     0  3.9G   0% /dev
tmpfs          tmpfs     3.9G     0  3.9G   0% /dev/shm
tmpfs          tmpfs     3.9G  401M  3.5G  11% /run
tmpfs          tmpfs     3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs          tmpfs     783M     0  783M   0% /run/user/0
0
>>> os.path.ismount('/')
True
>>> os.path.ismount('/dev')
True
>>> os.path.ismount('/usr')
False

>>> os.path.samefile('/etc/rc0.d', '/etc/rc0.d')
True
>>> os.path.samefile('/etc/rc0.d', '/etc/rc0.d/')
True

二、文件及目錄操作(os模塊)


需要說明的是: os模塊是一個混雜的操作系統接口模塊,它提供了各種操作系統相關的功能,文件及目錄操作只是其中一部分,而非全部。

在一些Unix平臺上,這個模塊的許多文件或目錄的操作函數都支持下面的一個或多個特性:

  • 指定一個文件描述符 對于某些函數,path參數不僅僅可以是一個字符串,還可以是一個文件描述符。該函數會操作這個文件描述符引用的文件。我們可以通過os.supports_fd來檢查當前平臺path參數是否可以指定為一個文件描述符,如果不可用將會引發一個NotImplementedError。如果該函數還支持dir_fd或follow_symlinks參數,當path被以文件描述符的方式提供時,指定dir_fd或follow_symlinks參數是錯誤的。
  • 相對于目錄描述符的路徑 如果dir_fd不是None,它應該是一個指向某個目錄的文件描述符,并且要操作的path應該是一個相對于該目錄的相對路徑;如果path是一個絕對路徑,dir_fd將會被忽略。
  • 不遵循符號鏈接 如果follow_symlinks是False,并且要操作的路徑中最后一個元素是一個符號鏈接時,該函數將會操作這個鏈接文件,而不是操作這個鏈接文件指向的文件。

1. 相關方法列表

# 測試當前用戶是否對path所對應文件有某種訪問權限
# Python2
os.access(path, mode)
# Python3
os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)

# 更改當前工作目錄,從Python3.3開始path參數允許是一個目錄的文件描述符
os.chdir(path)

# 更改當前工作目錄,從Python3.3開始該函數等價于os.chdir(fd)
os.chfdir(fd)

# 更改文件或目錄權限,dir_fd和follow_symlinks是Python3.3新增的參數
os.chmod(path, mode, *, dir_fd=None, follow_symlinks=True)

# 更改文件或目錄權限,如果path是個鏈接文件則影響是鏈接文件本身;Python3.3開始該函數等價于os.chmod(path, mode, follow_symlinks=False)
os.lchmod(path, mode)

# 更改文件或目錄的屬主和屬組,如果不改變則設置為-1;dir_fd和follow_symlinks是Python3.3新增的參數
os.chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)

# 更改文件或目錄的屬主和屬組,如果不改變則設置為-1;如果path是個鏈接文件則影響是鏈接文件本身;Python3.3開始該函數等價于os.chown(path, uid, gid, follow_symlinks=False)
os.lchown(path, uid, gid)

# 更改當前進程主目錄
os.chroot(path)

# 返回一個表示當前目錄的字符串
os.getcwd()

# 返回一個表示當前目錄的字節串,Python3新添加的函數
os.getcwdb()

# 創建硬鏈接, *后面的參數都是Python3.3新增的
os.link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)

# 創建軟鏈接,*后面的參數都是Python3.3新增的
os.symlink(src, dst, target_is_directory=False, * dir_fd=None)

# 返回指定目錄中所有文件列表,順序不固定,且不包含‘.’和‘..’;注意path在Python2中沒有默認值
os.listdir(path='.')

# 返回指定目錄中所有文件條目對應的DirEntry對象迭代器,順序不固定,則不包含'.'和‘..’;Python3.5新增的函數
os.scandir(path='.')

# 獲取文件或文件描述的狀態信息,染回一個stat_result對象,dir_fd和follow_symlinks都是Python3.3新增的參數
os.stat(path, *, dir_fd=None, follow_symlinks=True)

# 獲取文件或文件描述的狀態信息,如果path是一個鏈接文件則獲取的是鏈接文件本身的狀態信息;Python3.3開始,該函數等價于os.stat(path, dir_fd=dir_fd, folow_symlinks=False)
os.lstat(path, *, dir_fd=None)

# 創建一個名為path的目錄并指定目錄權限,如果目錄已經存在則會引起FileExistsError;dir_fd是Python3.3開始新加的參數。需要說明的是該函數與os.makedirs()、os.mkfifo()函數創建的目或逛到文件的權限會受到umask的影響,比如指定mode為0777,實際目錄權限為 0777 - umask = 0755
os.mkdir(path, mode=0o777, *, dir_fd=None)

# 遞歸創建目錄,該函數功能與mkdir()相似,但是會遞歸創建所有的中間目錄;exist_ok為Python3.2新增參數,表示當目錄已經存在時是否正常返回,如果exist_ok為False(默認)且目標目錄已經存在則會引發OSError
os.makedirs(name, mode=0o777, exists_ok=False)

# 創建一個FIFO(命名管道)文件,FIFO可以被當做正常文件那樣訪問;通常FIFOs被用作‘client’和‘server’類型進程的匯集點,server打開FIFO讀取數據,client打開FIFO寫入數據。
os.mkfifo(path, mode=0o666, *, dir_fd=None)

# 刪除指定的文件,如果path是個目錄將會引發OSError
os.remove(path, *, dir_fd=None)
os.unlink(path, *, dir_fd=None)

# 刪除指定的空目錄,如果目錄不為空會引發OSError
os.rmdir(path, *, dir_fd=None)

# 遞歸刪除指定路徑中的所有空目錄
os.removedirs(name)

# 目錄或文件重命名,如果dst是一個目錄將會引發OSError。在Unix平臺上,如果dst存在且是一個文件,那么只要用戶有權限就將會被靜默替換;而在Windows平臺上,如果dst存在,即使它是一個文件也會引發OSError
os.rename(src, dst, *, src_dir_fd=-None, dst_dir_fd=None)

# 目錄或文件遞歸重命名
os.renames(old, new)

# 與os.rename()功能相同,區別在于:對于os.replace()來說,如果dst存在且是一個文件,那么只要用戶有權限就將會被靜默替換,而沒有平臺上的差別
os.replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)

# 返回鏈接文件指向的真實路徑,類似于os.path.relpath(path),但是該方法可能返回相對路徑
os.readlink(path, *, dir_fd=None)

# 返回一個文件的某個系統配置信息,name表示配置項名稱,可以通過os.pathconf_names來查看可用的值
os.pathconf(path, name)

關于os.access()函數的說明:默認以用戶的真實uid(RUID)和gid來對文件的訪問權限做檢測,但是大部分操作將會使用有效uid(EUID)或gid去做檢測,且Python3中可以通過將effective_ids參數設置為Ture來使用有效uid/gid來做權限檢測(關于RUID/EUID/SUID的概念可以參考<<這篇文章>>
)。mode可取值為:os.F_OK(文件存在)、os.R_OK(可讀)、os.W_OK(可寫)、os.X_OK(可執行)中的一個或用邏輯運算符‘|’連接起來的多個。

2. 實例

>>> import os
>>> 
>>> os.access('/bin/passwd', os.F_OK)
True
>>> os.access('/bin/passwd', os.F_OK|os.X_OK)
True
>>> os.access('/bin/passwd', os.F_OK|os.W_OK)
True

>>> os.getcwd()
'/root'
>>> os.chdir('/tmp')
>>> os.getcwd()
'/tmp'

>>> os.system('ls -l test*')
-rw-r--r-- 1 root root 0 Feb  9 09:02 test1.txt
lrwxrwxrwx 1 root root 9 Feb  9 09:02 test.txt -> test1.txt
0
>>> os.chmod('/tmp/test.txt', 0666)
>>> os.system('ls -l test*')
-rw-rw-rw- 1 root root 0 Feb  9 09:02 test1.txt
lrwxrwxrwx 1 root root 9 Feb  9 09:02 test.txt -> test1.txt
0

>>> os.link('test.txt', 'test')
>>> os.system('ls -li test*')
271425 lrwxrwxrwx 2 root  root  9 Feb  9 09:02 test -> test1.txt
271379 -rw-rw-rw- 1 mysql mysql 0 Feb  9 09:02 test1.txt
271425 lrwxrwxrwx 2 root  root  9 Feb  9 09:02 test.txt -> test1.txt
0

>>> os.listdir('.')
['zabbix_proxy.log', 'test.txt', 'zabbix_agentd.log', '.Test-unix', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-systemd-machined.service-gJk0Cd', 'hsperfdata_root', 'wrapper-31124-1-out', 'a', 'test1.txt', 'zabbix_proxy.log.old', 'zabbix_agentd.log.old', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-mariadb.service-kudcMu', 'test', '.X11-unix', '.font-unix', 'wrapper-31124-1-in', '.XIM-unix', '.ICE-unix', 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>']
>>> os.listdir('/tmp')
['zabbix_proxy.log', 'test.txt', 'zabbix_agentd.log', '.Test-unix', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-systemd-machined.service-gJk0Cd', 'hsperfdata_root', 'wrapper-31124-1-out', 'a', 'test1.txt', 'zabbix_proxy.log.old', 'zabbix_agentd.log.old', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-mariadb.service-kudcMu', 'test', '.X11-unix', '.font-unix', 'wrapper-31124-1-in', '.XIM-unix', '.ICE-unix', 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>']

>>> os.mkdir('/tmp/testdir')
>>> os.system('ls -l /tmp')
lrwxrwxrwx 2 root   root         9 Feb  9 09:02 test -> test1.txt
-rw-rw-rw- 1 mysql  mysql        0 Feb  9 09:02 test1.txt
drwxr-xr-x 2 root   root      4096 Feb  9 09:47 testdir
lrwxrwxrwx 2 root   root         9 Feb  9 09:02 test.txt -> test1.txt
>>> os.mkdir('/tmp/testdir')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 17] File exists: '/tmp/testdir'
>>> os.mkdir('/tmp/a/b/c')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/tmp/a/b/c'
>>> os.makedirs('/tmp/a/b/c')  # mode默認為0777,結果卻是0755,bug?
>>> os.makedirs('/tmp/b/c/d', 0700)
>>> os.system('ls -l /tmp')
total 2316
drwxr-xr-x 3 root   root      4096 Feb  9 10:16 a
drwx------ 3 root   root      4096 Feb  9 10:16 b
lrwxrwxrwx 2 root   root         9 Feb  9 09:02 test -> test1.txt
-rw-rw-rw- 1 mysql  mysql        0 Feb  9 09:02 test1.txt
drwxr-xr-x 2 root   root      4096 Feb  9 09:47 testdir
lrwxrwxrwx 2 root   root         9 Feb  9 09:02 test.txt -> test1.txt

>>> os.rename('/tmp/test1.txt', '/tmp/test3.txt')
>>> os.system('ls -l /tmp')
lrwxrwxrwx 2 root   root         9 Feb  9 09:02 test -> test1.txt
prw-r--r-- 1 root   root         0 Feb  9 10:21 test1.fifo
-rw-rw-rw- 1 mysql  mysql        0 Feb  9 09:02 test3.txt
drwxr-xr-x 2 root   root      4096 Feb  9 09:47 testdir
prw-r--r-- 1 root   root         0 Feb  9 10:20 test.fifo
lrwxrwxrwx 2 root   root         9 Feb  9 09:02 test.txt -> test1.txt

>>> os.readlink('/tmp/test.txt')
'test1.txt'

>>> os.rmdir('/tmp/testdir')
>>> os.rmdir('/tmp/a/b/c')  # 只刪除空目錄/tmp/a/b/c
>>> os.removedirs('/tmp/b/c/d')  # 先刪除空目錄/tmp/a/b/c,然后刪除空目錄/tmp/a/b,最后刪除目錄/tmp/a,而目錄/tmp非空,因此不會被刪除

>>> os.unlink('/tmp/test')
>>> os.unlink('/tmp/test.fifo')
>>> os.unlink('/tmp/test.txt')
>>> os.system('ls -l /tmp')
>>> os.remove('/tmp/test3.txt')
>>> os.remove('/tmp/test1.fifo')

三、文件壓縮(zipfile模塊)


1. zipfile模塊包含的類

顧名思義,zipfile模塊用于文件的壓縮操作,該模塊包含以下幾個類:

類名 描述
zipfile.ZipFile 用于ZIP文件的讀寫操作
zipfile.PyZipFile 用于創建包含Python庫的ZIP歸檔文件
zipfile.ZipInfo 用于表示歸檔文件中的一個成員信息

zipfile.ZipInfo類的實例可以通過ZipFile對象的getinfo()和infolist()方法獲取。

2. zipfile模塊中的函數和常量

函數/常量名 描述
zipfile.is_zipfile(filename) 判斷filename是否是一個有效的ZIP文件,并返回一個布爾類型的值
zipfile.ZIP_STORED 表示一個壓縮的歸檔成員
zipfile.ZIP_DEFLATED 表示普通的ZIP壓縮方法,需要zlib模塊的支持
zipfile.ZIP_BZIP2 表示BZIP2壓縮方法,需要bz2模塊的支持;Python3.3新增
zipfile.ZIP_LZMA 表示LZMA壓縮方法,需要lzma模塊的支持;Python3.3新增

3. zipfile.ZipFile類

類的構造方法

class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True)

創建一個ZipFile實例,表示打開一個ZIP文件。

參數:

  • file:可以是一個文件的路徑(字符串),也可以是一個file-like對象;
  • mode:表示文件代開模式,可取值有:r(讀), w(寫), a(添加), x(創建和寫一個唯一的新文件,如果文件已存在會引發FileExistsError)
  • compression:表示對歸檔文件進行寫操作時使用的ZIP壓縮方法,可取值有:ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA, 傳遞其他無法識別的值將會引起RuntimeError;如果取ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA,但是相應的模塊(zlib, bz2, lzma)不可用,也會引起RuntimeError;
  • allowZip64:如若zipfile大小超過2GiB且allowZip64的值為False,則將會引起一個異常

說明:

  • 從Python 3.2開始支持使用ZipFile作為上下文管理器(with語法)
  • 從Python 3.3開始支持bzip2和lzma壓縮
  • 從Python 3.4開始allowZip64默認值改為True
  • 從Python 3.5開始添加對unseekable streams的寫操作支持以及對‘x’ mode的支持

實例方法列表

# 打印該歸檔文件的內容
printdir()

# 從歸檔文件中展開一個成員到當前工作目錄,memeber必須是一個完整的文件名稱或者ZipInfo對象,path可以用來指定一個不同的展開目錄,pwd用于加密文件的密碼
extract(memeber, path=None, pwd=None)

# 從歸檔文件展開所有成員到當前工作目錄,path和pwd參數作用同上,memebers必須是namelist()返回的list的一個子集
extractall(path=None, members=None, pwd=None)

# 返回一個與每一個歸檔成員對應的ZipInfo對象的列表
infolist()

# 返回歸檔成員名稱列表
namelist()

# 返回一個包含壓縮成員name相關信息的ZipInfo對象,如果name沒有被包含在該壓縮文檔中將會引發KeyError
getinfo(name)

# 將歸檔文件中的一個成員作為一個file-like對象展開;name是歸檔文件中的文件名或者一個ZipInfo對象
open(name, mode='r', pwd=None)

# 關閉該壓縮文件;退出程序前必須調用close()方法,否則一些必要記錄不會被寫入
close()

# 設置pwd作為展開加密文件的默認密碼
setpassword(pwd)

# 讀取歸檔文件中所有文件并檢查它們的完整性,返回第一個被損壞的文件名稱,或者None。對已關閉的ZipFile調用testzip()將會引發RuntimeError
testzip()

# 返回歸檔文件中name所指定的成員文件的字節。name是歸檔文件中的文件名稱或一個ZipInfo對象。該歸檔文件必須以讀(r)或追加(a)的模式打開。如果設置了pwd參數,則其將會覆蓋setpassword(pwd)方法設置的默認密碼。對一個已經關閉的ZipFile調用read()方法將會引發RuntimeError
read(name, pwd=Noneds)

# 將filename文件寫入歸檔文件,可以通過arcname指定新文件名(需要注意的是文件名中磁盤盤符和開頭的路徑分隔符都會被移除);compress_type表示壓縮方法,如果指定了該參數則會覆蓋ZipFile構造方法中的compression參數指定的值;要調用此方法,歸檔文件必須以'w', 'a'或'x'模式打開,如果對以'r'模式打開的ZipFile調用write()方法或者對已關閉的ZipFile調用write()方法將會引發RuntimeError
write(filename, arcname=None, compress_type=None)

# 將一個字節串寫入歸檔文件;zinfo_or_arcname可以是歸檔文件中的文件名稱,也可以是一個ZipInfo實例
writestr(zinfo_or_arcname, bytes[, compress_type])

4. zipfile.PyZipFile類

PyZipFile類用于創建包含Python庫的ZIP存檔

類的構造方法

PyZipFile的構造方法與ZipFile的構造方法參數基本一致,只是多了一個optimize參數

class zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=-1)

說明:

  • Python 3.2 新增optimize參數
  • Python 3.4 allowZip64默認值改為True

實例方法列表

PyZipFile類的實例方法與ZipFile類的實例方法一致,只是多了一個writepy()方法:

# 搜索*.py文件并將相應的文件添加到歸檔文件
writepy(pathname, basename='', filterfunc=None)

說明:

  • 如果該PyZipFile實例的構造方法中的optimize參數沒有被給出,或者被設置為-1,那么這里所指的“相應文件”是一個*.pyc文件,如果需要,會進行編譯。
  • 如果該PyZipFile實例的構造方法中的optimize參數值為0, 1或2,只有那些同樣優化等級(參考compile()函數)的文件會被添加到歸檔文件。
  • 如果pathname是一個文件,文件名必須以.py結尾,且僅僅是這些(*.py[co])文件被添加,不包含路徑信息;如果pathname是一個文件,但是不以.py結尾,將會引發RuntimeError。
  • 如若pathname是一個目錄,且這個目錄不是一個package目錄,則所有的(不包含路徑信息).py[co]文件將被添加;如果pathname是一個package目錄,則所有的.py[co]都會作為一個文件路徑被添加到這個package名稱下,并且如果任何子文件夾是package目錄,則會被遞歸添加。
  • basename僅供內部使用
  • filterfunc參數如果被給出,則其必須是一個只接收一個字符串參數的函數。每個文件路徑在被添加到歸檔之前都會作為參數傳遞給filterfunc所指定的函數。如果filterfunc返回False,則這個路徑將不會被添加,如果是一個目錄,則它的內容將會被忽略。
  • filterfunc參數是Python 3.4新加的。

5. zipfile.ZipInfo類

ZipInfo類的實例時通過ZipFile對象的getinfo()和infolist()方法返回的,其本身沒有對外提供構造方法和其他方法。每一個ZipInfo對象存儲的是ZIP歸檔文件中一個單獨成員的相關信息,因此該實例僅僅提供了以下屬性用于獲取歸檔文件中成員的信息。

屬性名稱 描述
ZipInfo.filename 文件名稱
ZipInfo.date_time 文件的最后修改日期和時間,這是一個tuple:(年, 月, 日, 時, 分, 秒)
ZipInfo.compress_type 壓縮類型
ZipInfo.comment 文件備注
ZipInfo.extra 擴展字段數據
ZipInfo.create_system ZIP歸檔的創建系統
ZipInfo.create_version 創建ZIP歸檔的PKZIP版本
ZipInfo.extract_version 展開ZIP歸檔所需要的PKZIP版本
ZipInfo.reserved 必須是0
ZipInfo.flag_bits ZIP標志位
ZipInfo.volume 文件頭的Volume號碼
ZipInfo.internal_attr 內部屬性
ZipInfo.external_attr 外部屬性
ZipInfo.header_offset 文件頭的字節偏移量
ZipInfo.CRC 未壓縮文件的CRC-32
ZipInfo.compress_size 壓縮后的數據大小
ZipInfo.file_size 未壓縮文件大小

6. 實例

實例1:文件歸檔與解壓縮操作

import zipfile

# 歸檔
z = zipfile.ZipFile('test.zip', 'w')
z.write('a.txt')
z.write('b.log')
z.close()

# 解壓
z = zipfile.ZipFile('test.zip', 'r')
z.extractall()
z.close()

# 文件信息讀取
z = zipfile.ZipFile('test.zip', 'r')
z.printdir()
z.namelist()
z.infolist()
zinfo = z.getinfo('a.txt')
print(zinfo.filename)
print(zinfo.date_time)
print(zinfo.file_size)
print(zinfo.compress_size)
z.close()

實例2:python文件歸檔

工程目錄結構

MYPROG
│  hello.py
│
├─account
│      login.py
│      __init__.py
│
├─test
│      test_print.py
│
└─tools
        tool.py

代碼

import zipfile
 
pyz = zipfile.PyZipFile('myprog.zip', 'w')
pyz.writepy('MYPROG/hello.py')
pyz.writepy('MYPROG/tools')
pyz.writepy('MYPROG/test')
pyz.writepy('MYPROG/account')
pyz.close()

pyz.printdir()

輸出結果:

File Name                                             Modified             Size
hello.pyc                                      2017-02-16 11:46:20          130
tool.pyc                                       2017-02-16 11:55:44          135
test_print.pyc                                 2017-02-16 11:55:48          140
account/__init__.pyc                           2017-02-16 11:55:54          118
account/login.pyc                              2017-02-16 11:55:54          138

四、文件打包(tarfile模塊)


tarfile模塊用于讀寫tar歸檔文件,它也可以同時實現壓縮功能。與zipfile模塊相比,tarfile模塊 可以直接將一個目錄進行歸檔并壓縮。另外,tarfile模塊提供的api更“面向對象”化。

1. tarfile模塊包含的兩個主要的類

類名 描述
TarFile 該類提供了操作一個tar歸檔的接口
TarInfo 一個TarInfo對象代表TarFile中的一個成員

這兩個類的關系類似于zipfile.ZipFile與zipfile.ZipInfo的關系,TarInfo對象中保存了一個文件所需要的所有屬性,比如:文件類型、文件大小、修改時間、權限、屬主等,但是它不包含文件的數據。

2.tarfile模塊包含的方法和常量

方法/常量名 描述
tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs) 為指定的路徑名name返回一個TarFile對象
tarfile.is_tarfile(name) 如果name是一個tarfile模塊可以讀的tar歸檔文件則返回True,否則返回False
tarfile.ENCODING 表示默認字符編碼,在windows上為'utf-8',否則為sys.getfilesystemencoding()的返回值
tarfile.USTAR_FORMAT POSIX.1-1922(ustar)格式
tarfile.GUN_FORMAT GUN tar格式
tarfile.PAX_FORMAT POSIX.1-2001(pax)格式
tarfile.DEFAULT_FORMAT 表示創建歸檔的默認格式,當前值為GUN_FORMAT

關于open()函數的說明:

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

該函數用于創建并返回一個TarFile對象。Python官方文檔不建議直接使用TarFile的構造方法構建示例,而是建議使用這個open()函數來操作TarFile對象。下面我們來說說它的參數:

  • name:表示要創建的歸檔文件的名稱,通常為.tar, .tar.gz, .tar.bz2, .tar.xz,具體后綴應該與mode的值對應
  • mode:必須是一個filemode[:compression]格式的字符串,默認值為'r'。filemode的可取值為'r', 'w', 'a', 'x'; compression表示壓縮方式,可取值為'gz', 'bz2', 'xz';需要注意的是'a:gz', 'a:bz2', 'a:xz'是不允許的格式。

下面是mode所有可取值的列表:

mode 行為
'r:' 以讀模式打開一個未壓縮的歸檔文件(通常后綴為*.tar)
'r:gz' 以讀模式打開一個通過gzip方式進行壓縮的歸檔文件(通常后綴為*.tar.gz)
'r:bz2' 以讀模式打開一個通過bzip2方式進行壓縮的歸檔文件(通常后綴為*.tar.bz2)
'r:xz' 以讀模式打開一個通過lzma方式進行壓縮的歸檔文件(通常后綴為*.tar.xz)
'r' 或 'r:*' 以讀模式打開歸檔文件,可以打開以上任意方式壓縮的歸檔文件,且會自動判斷應該使用的壓縮方式。推薦使用這個mode。
'w'或'w:' 以寫模式打開一個不進行壓縮的歸檔文件
'w:gz' 以寫模式打開一個以gzip方式進行壓縮的歸檔文件
'w:bz2' 以寫模式打開一個以bzip2方式進行壓縮的歸檔文件
'w:xz' 以寫模式打開一個以lzma方式進行壓縮的歸檔文件
'x'或'x:' 同'w'或'w:',但是如果歸檔文件已經存在會引發FileExistsError
'x:gz' 同'w:gz',但是如果歸檔文件已經存在會引發FileExistsError
'x:bz2' 同'w:bz2'',但是如果歸檔文件已經存在會引發FileExistsError
'x:xz' 同'w:xz',但是如果歸檔文件已經存在會引發FileExistsError
'a'或'a:' 以追加方式打開一個不進行壓縮的股低昂文件,如果文件不存在則創建

對于 'w:gz', 'r:gz', 'w:bz2', 'r:bz2', 'x:gz', 'x:bz2'這些模式, tarfile.open() 接收關鍵字參數 compresslevel (默認值為9) 來指定該歸檔文件的壓縮級別.

3.tarfile.TarFile類

類構的造方法

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類實例的屬性被訪問;
  • name:指定歸檔文件路徑名稱;如果fileobj參數被指定該參數可以被忽略,且如果fileobj的name屬性存在則取該屬性的值;
  • mode::指定文檔打開模式;r:讀取已存在的歸檔,a:向一個已存在的文件追加數據,w:創建一個新的文件覆蓋已經存在的文件,x:如果文件不存在才創建一個新文件
  • fileobj:指定要讀寫的文件對象;如果指定了該參數,那么mode參數的值會被fileojb的mode屬性值覆蓋,且name參數可以被忽略;
  • format:用于控制歸檔格式;必須是這些值中的一個:USTAR_FORMAT, GUN_FORMAT, PAX_FORMAT
  • tarinfo
  • dereference:如果該參數值為False,則直接將軟連接和硬鏈接添加到歸檔中;如果該參數值為True,則將目標文件的內容添加到歸檔中;
  • ignore_zeros:該參數值對讀取連續或損壞的歸檔時有效;如果值為False,則會把一個空block當做歸檔文件的結束位置;如果值為Ture,則會跳過空或無效的block并嘗試獲取盡可能多的歸檔成員
  • debug:設置調試級別,可取值為0(不輸出任何調試信息)至 3(輸出所有調試信息),調試信息會被寫到sys.stderr;
  • errorlevel:設置錯誤級別;如果值為0,則使用TarFile.extract()方法時出現的所有錯誤都會被忽略,否則,如果debug可用,這些信息會作為錯誤信息出現在debug輸出中。如果值為1,則所有fatal錯誤將會引發OSError;如果值為2,則所有非fatal錯誤將會引發TarError;
  • encoding 和 errors:這兩個參數定義了讀寫歸檔時使用的字符編碼和如何處理轉換錯誤

類方法

classmethod TarFile.open(...)

這是個可選的構造方法,實際上tarfile.open()函數就是這個函數的快捷方式

實例方法


# 將name文件添加到歸檔;name可以是任何類型的文件(如:目錄,fifo管道,軟連接等),arcname用于指定name文件被添加到歸檔后的新名字,arcname默認為None,表示文件名稱保持不變。recursive值為Trur表示如果name文件是一個目錄,則該目錄中文件會被遞歸添加到歸檔中。exclude參數如果被指定,則其值必須是一個接受文件名作為參數的函數,且該函數必須返回一個布爾值,返回值為True表示該文件將不會被添加到歸檔中,反之則會被添加到歸檔中。filter參數如果被提供,則它必須是一個關鍵字參數且它應該是一個接收TarInfo對象作為參數的函數,該函數應該返回被修改后的TarInfo對象;如果它的返回值為None,那么該TarInfo將不會被添加到歸檔中。需要說明的是,從Python 3.2開始 exclude參數被廢棄,新增filter參數,且使用filter代替exclude的功能
add(name, arcname=None, recursive=True, exclude=None, *, filter=None)

# 添加指定TarInfo對象到歸檔中。如果fileobj被提供,它應該是一個二進制文件,且會從這個二進制文件中讀取tarinfo.size字節的內容添加到這個歸檔中。你可以通過gettarinfo()直接創建TarInfo對象
addfile(tarinfo, fileobj=None)

# 返回歸檔成員name對應的TarInfo對象(類似zipfile.ZipFile實例的getinfo(name)方法);如果name無法在歸檔中找到會引發KeyError,如果一個成員在歸檔中不僅出現一次,則最后一次出現將被當做最新版本
getmemeber(name)

# 將歸檔中所有成員作為TarInfo對象的列表返回(類似zipfile.ZipFile實例的infolist()方法)
getmemebers()

# 將歸檔中所有成員的名稱以列表形式返回(類似zipfile.ZipFile實例的namelist()方法)
getnames()

# 打印內容列表到sys.stdout(類似zipfile.ZipFile實例的printdir()方法);如果verbose值為False,則僅打印成員的名稱;如果verbose值為True,則打印的內容類似'ls -l'命令的輸出;如果可選參數members被給出,它必須是getmembers()方法返回的列表的子集;Python 3.5新增memebers參數
list(verbose=True, *, memebers=None)

# (當以讀模式打開歸檔時)該方法以TarInfo對象的形式返回歸檔的下一個成員,如果已經沒有可用的成員則返回None
next()

# 將歸檔中的所有成員提取到當前工作目錄或path參數指定的目錄;如果memebers參數被指定,它必須是getmemebers()函數返回列表的子集;所有者、更改時間和權限等目錄信息會在所有成員被提取后設置;如果numberic_owner值為True,將使用tarfile的uid和gid數字來設置提取后文件的屬主和屬組,否則將使用叔叔和屬組的名字。Python 3.5中新增了number_owner參數
extractall(path=".", memebers=None, *, numeric_owner=False)

# 提取歸檔中的一個成員到當前工作目錄或path指定的目錄,member參數的值可以是一個文件名或一個TarInfo對象;Python 3.2添加了set_attrs參數,Python 3.5添加了numberic_owner參數
extract(member, path="", set_attrs=True, *, numberic_owner=False)

# 提取歸檔中的一個成員為一個文件對象,member參數的值可以是一個文件名或一個TarInfo對象;從Python 3.3開始,如果member是一個普通文件或是一個鏈接,該方法會返回一個io.BufferedReader對象,否則會返回None
extractfile(member)

# 通過對現有文件執行os.stat()操作的結果創建一個TarInfo對象;這個已存在的文件可以通過文件名name來指定,也而已通過文件對象fileobj來指定(文件描述符),文件被添加到歸檔后的文件名取值優先級為:arcname參數的值,fileobj.name屬性的值,name參數的值;你可以在通過addfile()方法將該文件添加到歸檔之前對TarInfo對象的一些屬性值進行修改
gettarinfo(name=None, arcname=None, fileobj=None)

# 關閉TarFile對象
close()

4. tarfile.TarInfo類

一個TarInfo對象表示TarFile中的一個成員。TarInfo對象中除了保存了一個文件所需要的所有屬性(比如:文件類型、文件大小、修改時間、權限、屬主等)之外,它還提供了一些用于判斷其文件類型的方法。需要注意的是,它不包含文件的數據。TarInfo對象可以通過TarFile的getmember()、getmembers()和gettarinfo()方法獲取。

類構造方法

class tarfile.TarInfo(name="")

類方法

# 從字符串緩沖區創建一個TarInfo對象并返回
classmethod TarInfo.frombuf(buf, encoding, errors)

從TarFile對象中讀取一個成員并將其作為一個TarInfo對象返回
classmethod TarInfo.fromtarfile(tarfile)

對象方法和屬性

方法/屬性名 描述
name 歸檔成員名稱
size 字節大小
mtime 最后更改時間
mode 權限位
type 文件類型,通常是以下幾個常量中的一個:REGTYPE, AREGTYPE, LINKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GUNTYPE_SPARSE。判斷一個TarInfo對象類型的更方便的方式是使用下面的is*()方法
linkname 目標文件名稱,這只是在TarInfo對象的類型是LINKTYPE和SYMTYPE時有效
uid 最初存儲該成員的用戶ID
gid 最初存儲該成員的組ID
uname 用戶名
gname 組名
pax_headers 一個包含pax擴展頭的key-value字典
isfile() / isreg() 判斷TarInfo對象是否是一個普通文件
isdir() 判斷TarInfo對象是否是一個目錄
issym() 判斷TarInfo對象是否是一個軟鏈接
islnk() 判斷TarInfo對象是否是一個硬鏈接
ischr() 判斷TarInfo對象是否是一個字符設備
isblk() 判斷TarInfo對象是否是一個塊設備
isfifo() 判斷TarInfo對象是否是一個FIFO管道
isdev() 判斷TarInfo對象是否是一個字符設備 或 塊設備 或 FIFO管道
tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape') 從一個TarInfo對象生成一個字符串緩沖區

5. 實例

工程目錄結構:

MYPROG
│  hello.py
│
├─account
│      login.py
│      __init__.py
│
├─test
│      test_print.py
│
└─tools
        tool.py

Python工程歸檔及解壓操作:

import tarfile

# 歸檔壓縮
tf = tarfile.open('myprog.tar.gz', 'w:gz')
tf.add("MYPROG")
tf.close()

# 解壓
tf = tarfile.open('myprog.tar.gz')
tf.extractall()
tf.close()

# 讀取歸檔文件內容
tf = tarfile.open('myprog.tar.gz')
tf.list()
print(tf.getmembers())
f = tf.getmember('MYPROG/hello.py')
print(f.name)
print(f.size)
f.isfile()
tf.close()

五、高級文件和目錄處理(shutil模塊)


上面我們介紹了路徑操作(os.path模塊)、文件和目錄操作(os模塊)和 文件歸檔壓縮操作(zipfile模塊和tarfile模塊),但是還是這些模塊要么缺少一些常用的功能(如:文件復制、刪除非空文件夾),要么使用起來不是那么方便,而shutil模塊shutil提供了一些文件和文件集合的高級操作,可以彌補這些不足。

需要注意的是:雖然shutil.copy()和shutil.copy2()是高級復制函數,但是它們并不能拷貝所有的文件元數據(metadata),例如在POSIX平臺上,文件的屬主、屬組和ACLs等信息都會丟失。

1. 文件和目錄操作

# 文件內容(部分或全部)復制,參數是兩個已經打開的文件對象;length是一個整數,用于指定緩沖區大小,如果其值是-1表示一次性復制,這可能會引起內存問題
shutil.copyfileobj(fsrc, fdst[, length])

# 文件內容全部復制(不包括metadata狀態信息), 參數是兩個文件名,且dst必須是完整的目標文件名稱;如果dst已經存在則會被替換;follow_symlinks是Python 3.3新增的參數,且如果它的值為False則將會創建一個新的軟鏈接文件
shutil.copyfile(src, dst, *, follow_symlinks=True)

# 僅拷貝文件權限(mode bits),文件內容、屬組、屬組均不變,參數是兩個文件名;follow_symlinks是Python 3.3新增的參數
shutil.copymode(src, dst, *, follow_symlinks=True)

# 僅拷貝文件狀態信息(包括文件權限,但不包含屬主和屬組):mode bits, atime, mtime, flags,參數是兩個文件名;follow_symlinks是Python 3.3新增的參數
shutil.copystat(src, dst, *, follow_symlinks=True)

# 拷貝文件內容和權限,并返回新創建的文件路徑;相當于copyfile + copymode,參數是兩個路徑字符串,且dst可以是一個目錄的路徑;follow_symlinks是Python 3.3新增的參數
shutil.copy(src, dst, *, follow_symlinks=True)

# 與copy函數功能一致,只是會把所有的文件元數據都復制;相當于copyfile + copystat,也相當于 'cp -p'(不包括屬主和屬組);follow_symlinks是Python 3.3新增的參數
shutil.copy2(src, dst, *, follow_symlinks=True)

# 這個工廠方法接收一個或多個通配符字符串,然后創建一個可以被傳遞給copytree()方法的'ignore'參數的函數。文件名與指定的通配符匹配時,則不會被賦值。
shutil.ignore_patterns(*patterns)

# (遞歸)拷貝整個src目錄到目標目錄dst,且目標目錄dst必須是不存在的。該函數相當于 'cp -pr';目錄的權限和時間通過shutilcopystat()來拷貝,單個文件通過shutil.copy2()來拷貝
shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)

# 遞歸刪除,相當于 rm -r
shutil.rmtree(path, ignore_errors=False, onerror=None)

# 遞歸移動并返回目標路徑,相當于move命令;如果dst是一個已經存在的目錄,則src將會被移動到該目錄里面;如果dst已經存在,但不是目錄,他將會被覆蓋;copy_function是Python 3.5新加的關鍵字參數
shutil.move(src, dst, copy_function=copy2)

# 以一個命名tuple的形式返回磁盤使用信息(total, used, free),單位為字節;Python 3.3新增方法
shutil.disk_usage(path)

# 更改指定路徑的屬主和屬組,user可以是一個系統用戶名或一個uid,group也是這樣;這兩個參數至少要提供一個;Python 3.3新增方法
shutil.chown(path, user=None, group=None)

# 返回命名cmd的文件路徑,相當于which命令;Python 3.3新增方法
shutil.which(cmd, mode=os.F_OK|os.X_OK, path=None)

2. 歸檔操作

shutil模塊的當當操作是創建和讀取壓縮文件的高級工具,同時提供文檔歸檔功能。這些高級工具的實現是基于zipfile和tarfile模塊實現的,其中與make_archive相關的函數是在Python 2.7版本新增的,而與unpack_archive相關的函數是在Python3.2版本新增的。

# 創建一個歸檔文件(zip或tar)并返回它的名字;
# basename是要創建的文件名稱,包含路徑,但是不包含特定格式的擴展名;
# format是歸檔格式,可取值為'zip', 'tar', 'gztar', 'bztar'和 ‘xztar’ 
# root_dir表示歸檔文件的根目錄,即在創建歸檔之前先切換到它指定的目錄,
# base_dir表示要進行歸檔的目錄,如果沒有提供則對root_dir目錄下的所有文件進行歸檔壓縮(它可以是絕對路徑,也可以是相對于root_dir的相對路徑,它將是歸檔中所有文件和目錄的公共前綴)
# root_dir和base_dir默認都是當前目錄
# dry_run如果值為Ture表示不會創建歸檔,但是操作輸出會被記錄到logger中,可用于測試
# loggger必須是一個兼容PEP 282的對象,通常是logging.Logger的一個實例
# verbose該參數沒有用處且已經被廢棄
# Python 3.5新增對xztar格式的支持
shutil.make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,
                    dry_run=0, owner=None, group=None, logger=None)

# 解壓歸檔文件
# filename是歸檔文件的全路徑
# extract_dir時解壓歸檔的目標目錄名稱,如果沒有提供,則取當前工作目錄
# format是歸檔格式:'zip', 'tar' 或 'gztar'中的一種。或者是通過register_unpack_format()注冊時的其他格式,如果未提供則會根據歸檔文件的擴展名去查找相應的解壓器,如果沒找到則會引發ValueError。
shutil.unpack_archive(filename[, extract_dir[, format]])

# 返回支持的歸檔格式列表,且該列表中的每個元素是一個元組(name, description)
# shutil默認提供以下歸檔格式:
# gztar: gzip'ed tar-file
# bztar: bzip2'ed tar-file(如果bz2模塊可用)
# xztar: xz'ed tar-file(如果lzma模塊可用)
# tar: uncompressed tar file
# zip: ZIP file
# 我們可以通過register_archive_format()來注冊新的歸檔格式或者為已存在的格式提供我們自己的歸檔器
shutil.get_archive_formats()

# 以列表形式返回所有已注冊的解壓格式,每個列表中的每個元素都是一個元組(name, extensions, description)
# shutil默認提供的解壓格式與shutil.get_archive_formats()返回結果一直
# 我們可以通過register_unpack_format()來注冊新的格式或為已存在的格式提供我們自己的解壓器
shutil.get_unpack_formats()

# 注冊一個新的歸檔格式對應的歸檔器
shutil.register_archive_fromat(name, function[, extra_args[, description]])

# 從支持的歸檔格式列表中移除指定的歸檔格式
shutil.unregister_archive_fromat(name)

# 注冊一個新的解壓格式對應的解壓器
shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])

# 從支持的解壓格式列表中移除指定的擠壓格式
shutil.unregister_unpack_format(name)

3. 實例

shutil.copyfile('/tmp/myprog/hello.py', '/tmp/hello.py')
# 僅復制文件內容
# -rw-r--r-- 1 root root 46 Feb 21 16:22 /tmp/hello.py

shutil.copymode('/tmp/myprog/hello.py', '/tmp/hello.py')
# 僅復制文件權限位
# -rwxr-xr-x 1 root root 46 Feb 21 16:46 /tmp/hello.py

shutil.copystat('/tmp/myprog/hello.py', '/tmp/hello.py')
# 僅復制文件元數據(atime, mtime)
# -rwxr-xr-x 1 root root 46 Feb 18 17:32 /tmp/hello.py

shutil.copy('/tmp/myprog/hello.py', '/tmp/hello1.py')
# 復制文件內容和權限位
# -rwxr-xr-x 1 root root 46 Feb 21 16:54 /tmp/hello1.py

shutil.copy2('/tmp/myprog/hello.py', '/tmp/hello2.py')
# 同時復制文件內容、權限為和時間
# -rwxr-xr-x 1 root root 46 Feb 18 17:32 /tmp/hello2.py

shutil.copytree('/tmp/myprog', '/tmp/myprog1')
# 復制一個目錄(包括子目錄和文件)

shutil.move('/tmp/myprog1', '/tmp/myprog2')
# 移動文件或目錄,也可以看做是“重命名”

shutil.rmtree('/tmp/myprog2')
# 刪除一個目錄(包括子目錄和文件)

shutil.make_archive('/data/myprog', 'gztar', root_dir='/tmp/', base_dir='myprog')
# 切換到/tmp目錄下,將myprog目錄以gzip的格式進行歸檔壓縮,壓縮文件路徑為/data/myprog.tar.gz

六、其他相關模塊(tempfile和fileinput模塊)


tempfile模塊用于創建和操作臨時文件;fileinput模塊用于同時讀取多個文件的內容(包括sys.stdin)。這兩個模塊比較簡單,大家自己翻下官方文檔就可以了。

七、總結


  1. 使用os.path模塊進行路徑相關操作,如:路徑分割,路徑拼接,獲取路徑對應文件的大小、絕對路徑、3個時間屬性、目錄名(dirname)和文件名(basename),判斷路徑對應文件的類型等;
  2. 使用os模塊進行文件及目錄相關基礎操作,如:刪除單個文件或空目錄,設置文件或目錄的權限和屬主、屬組,文件和目錄的移動、重命名,創建目錄、層級目錄、FIFO管道文件、硬鏈接和軟鏈接(創建普通文件使用open()函數),判斷有無對文件或目錄有指定的權限,查詢指定目錄下的所有文件列表等;
  3. 使用shutil模塊進行高級文件和目錄操作,如:文件(內容、權限位、時間屬性、全部)復制,目錄遞歸復制、非空目錄遞歸刪除;
  4. 使用zipfile或tarfile模塊進行文件的歸檔壓縮操作,shutil模塊提供的解壓函數是Python 3.2版本才提供的,因此對于使用Python 2進行開發的項目是無法使用shutil模塊提供的所有功能函數的;當然運維的同學有時也會直接執行tar命令是實現壓縮和解壓縮,但是跨平臺性就無法保證了。

問題交流群:666948590


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()