Python操作文件和目錄
讀寫文件比較簡單,有一點特別注意就好了
windows下Python默認打開的文件以gbk解碼,而一般我們的文件是utf-8編碼的,所以如果文本含有中文,就會出現異常或者亂碼。此時手動添加encoding='utf-8'
表示以utf-8的方式打開。
當然Python寫入時候,也是默認以gbk的編碼寫入。而文件通常是utf-8格式保存的,所以若不指定寫入的編碼方式,一寫入中文就是亂碼了
with open('abc.txt', encoding='utf-8') as f:
print(f.read()) # 這樣打開文件有中文也不怕
# 當然Python寫入時候,默認以gbk的編碼寫入。而文件是utf-8格式保存的,所以不指定寫入的編碼方式,一寫入中文就是亂碼了
with open('abc.txt', 'w', encoding='utf-8') as f:
f.write('你好')
好了進入正題
os模塊
當前工作目錄
下面的代碼可獲取/切換當前工作目錄,也就是.
代表的路徑
import os
print(os.getcwd()) # F:\PythonProject
os.chdir(r'D:\python')
print(os.getcwd()) # D:\python
print(os.path.abspath('.')) # D:\python
# 由于工作目錄切換到D:\python,所以這個aa.txt就在其下生成
with open('aa.txt', 'w', encoding='utf-8') as f:
f.write('你好')
os.chdir
可以切換當前的工作目錄,也就是改變了.
所指向的目錄。于是相對路徑aa.txt
就在切換后的路徑下生成。這兩個路徑表達同一個意思
aa.txt
.\aa.txt
還有兩個點,表示當前目錄的父目錄。..\aa.txt
這樣就是D:\aa.txt
的意思了。
絕對路徑和相對路徑
- 絕對路徑指的是從根文件夾子(盤符)開始
- 相對路徑是相對于當前工作目錄
print(os.path.abspath('aa.txt')) # D:\python\aa.txt
print(os.path.isabs('aa.txt')) # False
print(os.path.isabs('.')) #False
上面的代碼,第一個函數返回參數路徑的絕對路徑,第二個函數用于檢查一個路徑是否是相對路徑。
獲取最后一個斜杠前后的路徑。
# 獲取最后一個斜杠后面的部分
print(os.path.basename(r'D:\python\aa.txt')) # aa.txt
print(os.path.dirname(r'D:\python\aa.txt')) # D:\python
# 當然使用下面的函數可以同時獲得以上兩者
print(os.path.split(r'D:\python\aa.txt')) # ('D:\\python', 'aa.txt')
以其他方式分割
print(os.path.splitext(r'D:\python\aa.txt')) # ('D:\\python\\aa', '.txt')
print(os.path.splitdrive(r'D:\python\aa.txt')) # ('D:', '\\python\\aa.txt')
os.path.splitext
這個函數以可以方便地獲取文件后綴名,如果提供地路徑是文件夾,那么返回空。
os.path.splitdrive
以盤符作為分隔。
注意,它們都返回元組。
檢查路徑
檢查一個路徑存不存在,是文件?還是文件夾?
print(os.path.isfile('D:\python')) # False
print(os.path.isdir('D:\python')) # True
print(os.path.exists('D:\python')) # True
創建文件夾
os.mkdir('D:\good') # True 只能建立一級不存在的目錄,若已存在會報錯
os.mkdir('D:\good\job') # True 注釋掉上一句,由于D:\good已經存在,這里相當于還是只新建了一級不存在的目錄
os.mkdir(r'D:\aa\bb') # 報錯!!由于aa和bb文件夾都不存在,找不到D:\aa路徑,故不能創建
os.makedirs(r'D:\aa\bb') # 此函數沒有上上面的限制,管他存不存在一股腦兒創建,反正最后會生成此路徑就是了。不過如果此路徑已經存在了,就會報錯了
由此可以看出os.makedirs
更常用,可以創建處路徑里所有的文件夾。而os.mkdir
還必須保證上級目錄存在,所以只能新建一級目錄。
連接路徑
print(os.path.join(r'D:\python', 'aa.txt')) # D:\python\aa.txt
這個函數也很常用,用于連接兩個路徑,組合成新路徑返回。
遍歷文件夾
# 返回元組,分別是當前文件夾路徑, 當前路徑下的子文件夾,當前路徑下的文件
for current_path, subfolders, filesname in os.walk(r'D:\Cleaner'):
print(f'{current_path}\n{subfolders}\n{filesname}')
print('-'*30)
os.walk
可以遞歸遍歷給定路徑下所有地文件和文件夾。看下該目錄下這個函數會打印什么。這個函數會返回一個元組,分別是(當前路徑, 該路徑下的所有文件夾, 該路徑下的所有文件),然后不斷遞歸深入,不斷返回這樣的元組。所以上面的for循環執行了多次,直到路徑最深處。
D:\Cleaner
['CCleaner']
['desktop.ini']
------------------------------
D:\Cleaner\CCleaner
['Lang']
['branding.dll', 'business.dat', 'CCleaner.dat', 'CCleaner.exe', 'ccleaner.ini', 'CCleaner64.exe', 'portable.dat']
------------------------------
....
刪除文件/文件夾
# 永久刪除,不進入回收站
os.remove(r'D:\aaaa.txt') # same as os.unlink()
# 目錄為空才能刪除, 只是刪除當前文件夾
os.rmdir(r'D:\aaa\bbb\ccc\eee')
# 這個方法也不能刪除非空目錄,但是刪除了空文件夾子eee后若發現父級文佳夾也空就一并刪除
os.removedirs(r'D:\aaa\bbb\ccc\eee') # 剩下D:\aaa\bbb
# 強力,該目錄下所有文件/文件夾全部刪除,不管內容空不空。慎用
shutil.rmtree(r'D:\aaa')
重命名
# 重命名文件夾,必須保證原路徑存在,目標路徑不能已存在
os.rename(r'D:\python', 'D:\good')
# 重命名文件,必須保證原路徑存在,目標路徑不能已存在
os.rename(r'D:\good\aa.txt', r'D:\good\bb.txt')
# 上面都不能再目標地址存在的情況下使用,這個函數粗暴,如果目標路徑已存在,則會覆蓋之,慎用
os.replace(r'D:\good\bb.txt', r'D:\good\cc.txt')
獲取文件的大小
得到文件的大小,以字節為單位
print(os.path.getsize(r'D:\good\cc.txt'))
shutil模塊
os模塊的功能相當強大,但是還有部分功能,比如復制/剪切文件和文件夾存在與shutil模塊中。
直接看代碼吧
copy
# 如果Movie目錄存在,則是把這個文件復制到了該目錄下。
des1 = shutil.copy(r'D:\findall.txt', r'E:\Movie')
# 如果沒有該目錄,則新建Mov文件,無后綴名
des2= shutil.copy(r'D:\findall.txt', r'E:\Mov')
# 當然指定了后綴名,就把源文件復制過去并重命名
des2= shutil.copy(r'D:\findall.txt', r'E:\Mov.txt')
# copy只復制最后訪問時間
des3 = shutil.copy(r'D:\findall.txt', r'E:\findit.txt')
# copy2同時拷貝所有元數據包括修改時間和最后訪問時間
des4 = shutil.copy2(r'D:\findall.txt', r'E:\find.txt')
# 不拷貝訪問時間和修改時間
des5 = shutil.copyfile(r'D:\findall.txt', r'E:\findaa.txt')
# 可以看到返回的是新文件所在的路徑
print(f'{des1}\n{des2}\n{des3}')
# 拷貝整個文件夾(里面所有內容)到另外一個文件夾,該文件夾不能是已經存在的文件夾
shutil.copytree(r'D:\abc', r'E:\Movie')
move
# 剪切文件, abc不存在就移動文件并改名為abc, abc目錄存在則放入該目錄
shutil.move(r'D:\findall.txt', r'E:\abc')
# 目標地址若是文件,則是移動并重命名
shutil.move(r'D:\findall.txt', r'E:\aa.txt')
# 剪切文件夾,如果目標目錄已經存在,則剪切并放入該目錄,如果目標目錄不存在,則相當于移動目錄到目標地址并重命名文件夾
shutil.move(r'D:\abc', r'E:\avb')
ok,對文件和目錄的操作也是日常生活中經常會使用到的。學習了這些已經可以自動完成很多操作了。
by @sunhaiyu
2017.6.26