前篇內容我們介紹了Python中關於文件的處理及磁碟文件讀寫機制(參見你了解文件緩存機制嗎?磁碟文件如何讀寫?Python中open函數詳解)。今天,我們來詳細了解一下使用Python如何獲取文件的詳細信息。
不同系統的文件處理機制
我們知道,對於文件,不同的作業系統有著不同的處理機制:
比如Linux作業系統,它秉持「一切皆文件」的理念,大到一個系統文件,小到一個配置或日誌文件,甚至系統運行狀態、進程、掛載磁碟等信息,都是通過系統內的文件展現給我們。另一方面,對於這些文件的處理,Linux系統有一套完善的權限分配機制,不同的用戶和用戶組對於該文件有不同的讀、寫及執行權限。
Windows系統雖然也有明確的權限分配機制,但是作為使用者,我們平時基本感覺不到這種權限分配的過程(除非出於安全考慮對某些文件進行特定的權限設置)。系統使用者登錄到作業系統後,當他讀寫一個文件時,作業系統會頻繁鎖定該用戶對於文件的獨佔訪問。
上面兩種作業系統之間的區別其實大家日常使用中也能發現:比如,你使用Windows觀看一個視頻文件,當你試圖刪除或者重命名該文件時,系統會提示文件正在被佔用而無法執行這類操作;而Linux系統則不然,當你在Linux系統中觀看視頻的同時,你可以重命名該視頻文件或者刪除它都可以。對於具有root權限的用戶,甚至可以使用'rm -rf /'清空系統內所有內容(對於專業人士來講,非常人性化的一個設計)。
我們知道,一般Linux系統中都是默認安裝Python的(Windows為什麼不默認安裝呢?有限的系統空間應該留給收費軟體,你說呢?)
通過上面的分析,對於文件的操作,比如該文件是否可讀、寫,可執行,是否應該被獨佔,系統是如何判斷呢?聰明的小夥伴可能猜到了,是通過文件的屬性來判斷的。那麼,作為Python如何獲取文件系統中任意文件的屬性信息呢?
獲取文件信息
Python內置os模塊中的stat()方法可以用來獲取一個文件的屬性及狀態信息
os.stat(path, *, dir_fd=None, follow_symlinks=True)
path:指定為一個字符串或一個打開的文件描述符
dir_fd:該參數僅適用於Unix平臺,不適用Windows平臺;如果不為空,它應該是一個指向目錄的文件描述符,此時要操作的路徑應該是相對路徑;如果路徑是絕對路徑,則忽略該參數
follow_symlinks:該參數如果為False,並且要操作的路徑的最後一個元素是符號連結,則該函數將在符號連結本身,而不是連結指向的文件(好繞口)。簡單來講,如果path中傳入一個快捷方式,並且該參數設為False(默認為True),則stat返回的結構是快捷方式信息,而不是它指向的文件本身。
貌似後兩個參數都沒什麼卵用。
下面我們來分別看一下如何使用該函數獲取文件信息。
import os
f_info = os.stat('windows-version.txt')
>>>f_info
os.stat_result(st_mode=33206, st_ino=281474977063003, st_dev=3125222198, st_nlink=1, st_uid=0, st_gid=0, st_size=37, st_atime=1577196217, st_mtime=1577196217, st_ctime=1577196166)
返回一個stat_result元組對象,我們看下都有哪些屬性:
st_mode:文件模式,文件類型和文件模式位(權限)。
st_ino:inode 節點號。
st_dev:該文件所在設備的標識符。
st_nlink:硬連結的數量。
st_uid:文件所有者的用戶標識符。
st_gid:文件所有者的組標識符。
st_size:文件大小(以字節為單位),如果是常規文件或符號連結。符號連結的大小是它所包含的路徑名的長度,而不是終止的空字節。
st_atime:最近訪問的時間以秒表示。
st_mtime:最近的內容修改時間以秒表示。
st_ctime:取決於平臺:Unix上最新的元數據更改時間,在Windows上創建的時間,以秒表示。
st_atime_ns:最近訪問的時間以納秒表示,以整數表示。
st_mtime_ns:最新內容修改的時間以納秒表示,以整數表示。
st_ctime_ns:取決於平臺:Unix上最新的元數據更改時間,在Windows上創建的時間,以納秒為單位表示為整數。那麼,問題是這些信息如何識別並利用呢?
os.stat和stat模塊的區別
細心的小夥伴肯定發現了,Python中除了os.stat()方法,還提供了一個stat模塊,這兩者有什麼區別呢?
簡單來講,os.stat()方法是把文件的屬性讀取出來並以stat_result元組對象形式返回,但是它的部分實現是通過調用stat模塊來實現的,當然這種實現並不是很容易讓人理解。比如:我們獲取到的屬性st_mode=33206, st_ino=281474977063003, st_dev=3125222198, st_nlink=1, st_uid=0, st_gid=0等之後,還是不知道這些屬性代表的意義,那麼,我們還需要用stat模塊中提供的接口來進一步進行處理。
下面我們利用前面獲取到的屬性值,將它還原為我們能讀懂的屬性內容。
還原屬性本質
獲取文件具體屬性值一般是這樣的
1.判斷文件類型:
mode = f_info[0]
mode = s[0]
if stat.S_ISREG(mode): #判斷是否一般文件
print('一般文件.')
elif stat.S_ISLNK(mode): #判斷是否連結文件
print('連結文件.')
elif stat.S_ISSOCK(mode): #判斷是否套接字文件
print('套接字文件.')
elif stat.S_ISFIFO(mode): #判斷是否命名管道
print('命名管道.')
elif stat.S_ISBLK(mode): #判斷是否塊設備(硬碟等)
print('塊設備.')
elif stat.S_ISCHR(mode): #判斷是否字符設備(鍵鼠)
print('字符設備.')
elif stat.S_ISDIR(mode): #判斷是否目錄
print('目錄.')
2.讀取權限信息
比如,我們需要知道文件的權限可以使用oct(mode)將權限信息轉化為類似「0o100666」這樣的內容,後三位就是權限信息(參見Linux權限相關內容)。獲取Windows系統文件權限貌似意義不大。
3.讀取並設置時間
我們看到,stat_result元組中有st_atime*、st_mtime*、st_ctime*這樣的時間屬性,分別表示訪問、修改、修改時間。它們是表示時間戳的一串整形數據,對於時間的設置及讀取,我們後面專題進行討論,這裡就不再贅述了。
4.設置st_mode屬性
stat.S_ISUID: 執行時設置用戶ID
stat.S_ISGID: 執行時設置組ID
stat.S_ENFMT: 強制記錄鎖定
stat.S_ISVTX: 執行之後保存文字和圖片
stat.S_IREAD: 所有者的讀權限
stat.S_IWRITE: 所有者的寫權限
stat.S_IEXEC: 所有者的執行權限
stat.S_IRWXU: 所有者的讀寫執行的權限
stat.S_IRUSR: 所有者的讀權限
stat.S_IWUSR: 所有者的寫權限
stat.S_IXUSR: 所有者的執行權限
stat.S_IRWXG: 同組用戶的讀寫權限
stat.S_IRGRP: 同組用戶的讀權限
stat.S_IWGRP: 同組用戶的寫權限
stat.S_IXGRP: 同組用戶的執行權限
stat.S_IRWXO: 其它組用戶的讀寫執行權限
stat.S_IROTH: 其它組用戶的讀權限
stat.S_IWOTH: 其它組用戶的寫權限
stat.S_IXOTH: 其它組用戶的執行權限
改變某一信息,直接拿mode與相應的stat.S_XXX執行'&'操作即可。我們通常使用os.chmod()來改變一個文件的屬性信息。如下:
os.chmod('windows-version.txt', f_info.st_mode & stat.S_IXUSR)
這樣,將該文件就有了所有者的執行權限。這樣的權限設置對於Windows系統來說意義不大,但是Linux系統使用這種方式可以替代內部的Shell實現,多了一種方案,不是嗎?在進行網絡安全編程時,使用Python改變文件屬性也是個常用的操作,大家務必要掌握哦。
對於上述屬性不是很清楚的小夥伴,抓緊時間惡補Linux系統管理的知識吧,這是個很有用、很人性化的系統(比較圖形界面),時間長了大家一定會喜歡這個系統的,不信你試試!給大家推薦一本Linux的書。一本是基礎知識,一本是伺服器架設相關知識,書寫得通俗易懂,可以作為工具書使用,我買了兩年了,至今還在讀……讀了這兩本書基本就算Linux系統管理入門了。
基礎學習知識:
伺服器架設知識(喜歡自己建站和網路安全的小夥伴一定要讀哦):
另外,推薦一本關於Python的極客編程的書籍,裡面講解了很多實用的案例,喜歡的小朋友抓緊時間入手哦。
好了,今天的內容就到這裡了。對於文件屬性的獲取和改變,你了解了嗎?應該知道,這些屬性大部分內容是針對Linux系統來獲取的,但是這些方法大部分同樣適用於Windows系統(除非文檔特殊說明)。
喜歡的朋友們點個關注吧。歡迎大家留言討論。愛好Python編程的小夥伴關注我,後續會陸續推出一些有關Python實戰的小技巧。
轉載請註明出處,百家號:Python高手養成