檔案操作

pivpi發表於2019-02-16

一 介紹

計算機系統分為:計算機硬體,作業系統,應用程式三部分。
我們用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

請輸入程式碼