一 介紹
計算機系統分為:計算機硬體,作業系統,應用程式三部分。
我們用python或其他語言編寫的應用程式若想要把資料永久儲存下來,必須要儲存於硬碟中,這就涉及到應用程式要操作硬體,眾所周知,應用程式是無法直接操作硬體的,這就用到了作業系統。作業系統把複雜的硬體操作封裝成簡單的介面給使用者/應用程式使用,其中檔案就是作業系統提供給應用程式來操作硬碟虛擬概念,使用者或應用程式通過操作檔案,可以將自己的資料永久儲存下來。
檔案路徑:
相對路徑:Linux和os x中用/,Windows中用,該位置相對於當前程式所在目錄
絕對路徑:同上,讀取系統任何地方檔案,由於在Python中是轉義符建議路徑前加上r
有了檔案的概念,我們無需再去考慮操作硬碟的細節,只需要關注操作檔案的流程:
1、開啟檔案,得到檔案控制程式碼並賦值給一個變數
f=open(`a.txt`,`r`,encoding=`utf-8`) # 預設開啟模式就為r
2、通過控制程式碼對檔案進行操作
data=f.read()
3、關閉檔案
f.close() #操作過程儲存在記憶體與快取中,在程式結束或者close之後寫入磁碟
上下文與回收
開啟一個檔案包含兩部分資源:作業系統級開啟的檔案+應用程式的變數。在操作完畢一個檔案時,必須把與該檔案的這兩部分資源一個不落地回收,回收方法為:
1、f.close() #回收作業系統級開啟的檔案
2、del f #回收應用程式級的變數
注意:其中del f一定要發生在f.close()之後,否則就會導致作業系統開啟的檔案還沒有關閉,白白佔用資源,而python自動的垃圾回收機制決定了我們無需考慮del f,這就要求我們,在操作完畢檔案後,一定要記住f.close()。如果程式存在bug,導致close()未執行,檔案不會關閉。
whit管理上下文:
with open(`a.txt`,`w`) as f:
pass
with open(`a.txt`,`r`) as read_f,open(`b.txt`,`w`) as write_f:
data=read_f.read()
write_f.write(data)
注意:當with程式碼塊執行完畢時,內部會自動關閉並釋放檔案資源。open()返回的檔案物件只在with內可用,如果要在外部訪問需將with內建立列表,再從外部使用
檔案編碼
f=open(...)是由作業系統開啟檔案,那麼如果我們沒有為open指定編碼,作業系統會用自己的預設編碼去開啟檔案,在windows下是gbk,在linux下是utf-8。
f=open(`a.txt`,`r`,encoding=`utf-8`)
二 檔案操作
操作檔案時,一般需要經歷如下步驟:
1、開啟檔案
檔案控制程式碼 = file(`檔案路徑`, `模式`)
注:python中開啟檔案有兩種方式,即:open(…) 和 file(…) ,本質上前者在內部會呼叫後者來進行檔案操作,推薦使用 open。
開啟檔案的模式有:
開啟檔案的模式有(預設為文字模式):
- r :只讀模式【預設模式,檔案必須存在,不存在則丟擲異常】
- w :只寫模式【不可讀;不存在則建立;存在則清空原內容寫入新內容】
- a :追加寫模式【不可讀;不存在則建立;存在則在游標位置追加內容】
非文字檔案,我們只能使用b模式,”b”表示以位元組的方式操作(無需考慮文字、圖片、視訊的格式):
- rb :只讀模式
- wb :修改並讀取
- ab :追加位元組
注意:以b方式開啟時,讀取到的內容是位元組型別,寫入時也需要提供位元組型別,不能指定編碼
其他模式
- “+” :表示可以同時讀寫某個檔案
- r+ :讀寫【可讀,可寫】#追加寫,檔案游標位置處,預設在開始位置
- w+ :寫讀【可讀,可寫】#清除覆蓋原有內容,預設游標位置在開始,用seek讀
- a+ :寫讀【可讀,可寫】#不清空在最後位置追加,用seek讀。
- x :只寫模式【不可讀】#不存在則建立,存在則報錯
- x+ :寫讀【可讀,可寫】
-
“U” :表示在讀取時,將 r n rn自動轉換成 n (與r或r+模式同使用)
rU r+U
操作檔案方法
import sys #系統函式
print(f.tell()) #返回游標位置
f.read() #從游標初讀取所有內容,並移動到末尾返回空字串即空行
f.read(3) #文字模式讀三個字元,b模式讀取3個位元組
f.readline() #讀取一行內容,游標移動到第二行首部
f.readlines() #讀取所有行內容,存放於列表中,在迴圈迭代時獲取
f.xreadlines() #可用於逐行讀取檔案,非全部
f.readinto() #讀取到緩衝區,不要用,將被遺棄
f.seek(0) #指定檔案中指標位置,0代表開始位置,不同於read。
f.seek(3,2) #從第三個位元組開始列印,seek應用,如斷點續傳
f.tell() #獲取當前指標位置
f.truncate() #截斷檔案,保留指定之前的資料。
注意:檔案的開啟方式必須可寫,不能用w或w+等方式開啟,因為那樣直接清空檔案了,所以truncate要在r+或a或a+等模式下測試效果.
f.write(“xx”) #文字模式寫入快取,b模式需要加.encode(`utf-8`)
f.flush() #立刻從記憶體刷到磁碟中及螢幕上
f.time.sleep(100)#100秒後寫入磁碟
f.close() #寫入磁碟或程式結束後寫入磁碟
f.stdout.write(“xx”) #向螢幕輸出內容,代表檔案寫、輸出,先進了快取
f.write(`1111n222n`) #針對文字模式的寫,需要自己寫換行符
f.write(`1111n222n`.encode(`utf-8`)) #針對b模式的寫,需要自己寫換行符
f.writelines([`333n`,`444n`]) #檔案模式,字串寫入檔案
f.writelines([bytes(`333n`,encoding=`utf8`),`444n`.encode(`utf-8`)]) #b模式
f.readable() #檔案是否可讀
f.writable() #檔案是否可寫
f.close() #關閉檔案
f.closed #檔案是否關閉
f.encoding #如果檔案開啟模式為b,否則沒有該屬性
f.fileno() #檔案描述符
f.isatty() #判斷檔案是否是同意tty裝置
f.next() #獲取下一行資料,不存在時報錯
練習:
列印一首詩
f 讀取一行,執行完後被回收,優化記憶體
利用b模式,編寫一個cp工具,要求如下:
1. 既可以拷貝文字又可以拷貝視訊,圖片等檔案
2. 使用者一旦引數錯誤,列印命令的正確使用方法,如usage:cp source_file target_file
請輸入程式碼