用 python 代碼對文件進行各類操做。python
基本構成:vim
f = open('文件路徑或者相對路',encoding='編碼方式',mode='模式') # 格式構成 cotent = f.read() print(content) f.close()
代碼解釋:編輯器
open:函數
內置函數,open 底層調用的是操做系統的接口。測試
f:編碼
變量,約定俗成的變量名有(f1,fh,file_handler,f_h),這個變量還有一個名字,叫文件句柄。對亠件進行的任何操做,都得經過文件句柄加'.'的方式。操作系統
encoding:指針
能夠不寫,若是不寫,默認的編碼本就是系統默認的編碼。code
Windows: gkb視頻
Linux: utf-8
MacOS: utf-8
mode:
就是定義你的操做方式:r 爲讀模式。
f.read():
你想操做文件,好比讀文件,給文件寫內容,等等,都必須經過文件句柄進行操做。
f.colse():
關閉文件。(必須關閉,不然會常駐內存。)
文件操做的三個步驟:
打開文件。
對文件句柄進行相應的操做。
關閉文件。
# 打開文件,獲得文件句柄並賦值給一個變量 f = open('文件.txt', 'r', encoding='utf-8') # 默認打開模式就爲 r # 經過句柄對文件進行操做 date = f.read() # 關閉文件 f.close()
報錯的緣由:
UnicodeDecodeError:文件存儲時與文件打開時編碼本不一致。
路徑分隔符產生的問題:
解決方法:在路徑前加個 r r'C:\Users\Desktop\文件.txt'
文件操做的讀,有四種模式(r、rb、r+、r+b),r+ 和 r+b 不經常使用, rb 操做的是非文本的文件,好比:圖片、視頻、音頻。每種模式有五種方法(read()、read(n)、readline()、readlines()、for)。
r 模式
以只讀方式打開文件,文件的指針將會放在文件的開頭。是文件操做最經常使用的模式,也是默認模式,若是一個文件不設置mode,那麼默認使用r模式操做文件。
舉例:
f = open('文件.txt', mode='r', encoding='utf-8') msg = f.read() f.close() print(msg)
read() 一次性所有讀取
read() 將文件中的內容所有讀取出來; 弊端:若是文件很大就會很是的佔用內存,容易致使內存崩潰。
f = open('測試', mode='r', encoding='utf-8') msg = f.read() f.close() print(msg) # 輸出結果: 這是一行測試 A:這是第二行 B:這是第三行 C:這是第幾行 D:這是我也不知道第幾行 就這麼地吧.
read(n) 指定讀取到什麼位置
在 r 模式下,n 按照字符讀取
f = open('測試', mode='r', encoding='utf-8') msg = f.read(4) f.close() print(msg) # 輸出結果: 這是一行
readline() 按行讀取
readline() 每次只讀取一行,注意: readline() 讀取出來的數據在後面都有一個\n,解決這個問題只須要在咱們讀取出來的文件後邊加一個strip()就OK了
f = open('測試', mode='r', encoding='utf-8') msg1 = f.readline() msg2 = f.readline().strip() msg3 = f.readline() msg4 = f.readline() f.close() print(msg1) print(msg2) print(msg3) print(msg4) # 輸出結果: 這是一行測試 A:這是第二行 B:這是第三行 C:這是第幾行
readlines() 返回一個列表
readlines() 返回一個列表,列表裏面每一個元素是原文件的每一行,若是文件很大,佔內存,容易崩盤。
f = open('測試', mode='r', encoding='utf-8') print(f.readlines()) # 還能夠這麼寫的,哈哈 f.close() # 輸出結果: ['這是一行測試\n', 'A:這是第二行\n', 'B:這是第三行\n', 'C:這是第幾行\n', 'D:這是我也不知道第幾行\n', '就這麼地吧.']
上面這四種都不太好,若是文件超大,內容超多,他們就很容易將內存撐爆,因此,咱們還有第五種方法。
for 循環
能夠經過for循環去讀取,文件句柄是一個迭代器,他的特色就是每次循環只在內存中佔一行的數據,很是節省內存。
f = open('測試', mode='r', encoding='utf-8') for line in f: print(line) # 去掉 \n 能夠這樣寫: print(line.strip()) # 這種方式就是在一行一行的進行讀取,它就執行了下邊的功能 ''' print(f.readline()) print(f.readline()) print(f.readline()) ....... ''' # 輸出結果: 這是一行測試 A:這是第二行 B:這是第三行 C:這是第幾行 D:這是我也不知道第幾行 就這麼地吧.
特別注意: 讀完的文件必定必需要關閉
rb 模式
rb模式:以二進制格式打開一個文件用於只讀。文件指針將會放在文件的開頭。記住下面講的也是同樣,帶b的都是以二進制的格式操做文件,他們主要是操做非文字文件:圖片,音頻,視頻等,而且若是你要是帶有b的模式操做文件,那麼不用聲明編碼方式。
f1 = open('圖片.jpeg', mode='rb') tu = f1.read() f1.close() print(tu) # 輸出結果: b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00H\x00H\x00\x00\xff\xe1\x00\xb0Exif\x............後面還有.老長老長了..此處省略了.
rb模式也有read read(n) readline(),readlines() for循環這幾種方法,這裏就不一一演示了。
文件操做的寫,有四種模式(w、wb、w+、w+b),w+ 和 w+b 不經常使用, wb 操做的是非文本的文件,好比:圖片、視頻、音頻。操做方法是:write('要寫入的內容')
w 模式
若是文件不存在,用 w 模式操做文件,它會先建立文件,而後寫入內容。
f = open('這是一個新建立的文件', encoding='utf-8', mode='w') f.write('果真是一個新建立的文件') f.close()
若是文件存在,利用w模式操做文件,先清空原文件內容,在寫入新內容。
f = open('這是一個新建立的文件', encoding='utf-8', mode='w') f.write('這是清空後從新寫入的內容') f.close()
wb 模式
wb模式:以二進制格式打開一個文件只用於寫入。若是該文件已存在則打開文件,並從開頭開始編輯,即原有內容會被刪除。若是該文件不存在,建立新文件。通常用於非文本文件如:圖片,音頻,視頻等。
>>舉個例子 :
我先以rb的模式將一個圖片的內容以bytes類型所有讀取出來,而後在以wb將所有讀取出來的數據寫入一個新文件,這樣我就完成了相似於一個圖片複製的流程。具體代碼以下:
# 第一步:將原圖片經過 rb 模式讀取出來。 f = open('圖片.jpeg', mode='rb') content = f.read() f.close() # 第二步:將讀取出來的數據經過 wb 模式寫入新文件。 f1 = open('圖片1.jpeg', mode='wb') f1.write(content) f1.close()
就是在文件中追加內容。這裏也有四種文件分類主要四種模式:a,ab,a+,a+b,咱們只講a
a 模式
若是文件不存在,利用a模式操做文件,那麼它會先建立文件,而後寫入內容。
f = open('追加文本', encoding='utf-8', mode='a') f.write('這個文件是沒有的,我是新建立的') f.close()
若是文件存在,利用a模式操做文件,那麼它會在文件的最後面追加內容。
f = open('追加文本', encoding='utf-8', mode='a') f.write('這是己存在的文件,我是新追加的內容') f.close()
我們還有一種模式沒有講,就是那種帶+號的模式。什麼是帶+的模式呢?+就是加一個功能。好比剛纔講的r模式是隻讀模式,在這種模式下,文件句柄只能進行相似於read的這讀的操做,而不能進行write這種寫的操做。因此咱們想讓這個文件句柄既能夠進行讀的操做,又能夠進行寫的操做,那麼這個如何作呢?這就是接下來要說這樣的模式:r+ 讀寫模式,w+寫讀模式,a+寫讀模式,r+b 以bytes類型的讀寫模式.........
在這裏我們只講一種就是r+,其餘的大同小異,本身能夠練練就好了。
#1. 打開文件的模式有(默認爲文本模式): r,只讀模式【默認模式,文件必須存在,不存在則拋出異常】 w,只寫模式【不可讀;不存在則建立;存在則清空內容】 a, 只追加寫模式【不可讀;不存在則建立;存在則只追加內容】 #2. 對於非文本文件,咱們只能使用b模式,"b"表示以字節的方式操做(而全部文件也都是以字節的形式存儲的,使用這種模式無需考慮文本文件的字符編碼、圖片文件的jgp格式、視頻文件的avi格式) rb wb ab 注:以b方式打開時,讀取到的內容是字節類型,寫入時也須要提供字節類型,不能指定編碼 #3,‘+’模式(就是增長了一個功能) r+,讀寫【可讀,可寫】 w+,寫讀【可寫,可讀】 a+,寫讀【可寫,可讀】 #4,以bytes類型操做的讀寫,寫讀,寫讀模式 r+b,讀寫【可讀,可寫】 w+b,寫讀【可寫,可讀】 a+b,寫讀【可寫,可讀】
r+ 模式 讀並追加 順序不能錯
r+: 打開一個文件用於讀寫。文件指針默認將會放在文件的開頭。
f = open('文件的讀寫.txt', encoding='utf-8', mode='r+') content = f.read() print(content) f.write('這是新寫入的內容') f.close()
注意:若是你在讀寫模式下,先寫後讀,那麼文件就會出問題,由於默認光標是在文件的最開始,你要是先寫,則寫入的內容會講原內容覆蓋掉,直到覆蓋到你寫完的內容,而後在後面開始讀取。
小總結:
三個大方向:
讀, 四種模式: r rb r+ r+b
寫, 四種模式 : w,wb, w+,w+b
追加 四種模式: a, ab, a+,a+b
相應的功能:
對文件句柄的操做:read read(n) readline() readlines() write()
f.tell() 獲取光標的位置 單位是:字節
f = open('測試', encoding='utf-8', mode='r') print(f.tell()) content = f.read() print(f.tell()) f.close() # 原文件內容 這是一行測試 A:這是第二行 B:這是第三行 C:這是第幾行 D:這是我也不知道第幾行 就這麼地吧. # 輸出結果: 0 # 開始的位置 122 # 結束的位置
f.seek() 調整光標的位置 (注意:移動單位是byte , 若是是utf-8的中文部分要是3的倍數)
f = open('測試', encoding='utf-8', mode='r') f.seek(9) content = f.read() print(content) f.close() # 原文件內容 這是一行測試 A:這是第二行 B:這是第三行 C:這是第幾行 D:這是我也不知道第幾行 就這麼地吧. # 輸出結果: 行測試 A:這是第二行 B:這是第三行 C:這是第幾行 D:這是我也不知道第幾行 就這麼地吧.
f.flush() 強制刷新
f = open('測試', encoding='utf-8', mode='w') f.write('fafdsfsfsadfsaf') f.flush() f.close()
with open() as ....
# 優勢1:不用手動關閉文件句柄 # 利用with上下文管理這種方式,它會自動關閉文件句柄。 with open('測試', encoding='utf-8', mode='r') as f: print(f.read()) # 優勢2:能夠加多個 open 操做 # 一個with 語句能夠操做多個文件,產生多個文件句柄。 with open('測試', encoding='utf-8', mode='r') as f,\ open('測試', encoding='utf-8', mode='w') as f1: print(f.read()) f1.write('kckckckckckckkck')
這裏要注意一個問題,雖然使用with語句方式打開文件,不用你手動關閉文件句柄,比較省事兒,可是依靠其自動關閉文件句柄,是有一段時間的,這個時間不固定,因此這裏就會產生問題,若是你在with語句中經過r模式打開t1文件,那麼你在下面又以a模式打開t1文件,此時有可能你第二次打開t1文件時,第一次的文件句柄尚未關閉掉,可能就會出現錯誤,他的解決方式只能在你第二次打開此文件前,手動關閉上一個文件句柄。
文件的數據是存放於硬盤上的,於是只存在覆蓋、不存在修改這麼一說,咱們平時看到的修改文件,都是模擬出來的效果,具體的說有兩種實現方式:
文件操做改的流程:
1,以讀的模式打開原文件。
2,以寫的模式建立一個新文件。
3,將原文件的內容讀出來修改爲新內容,寫入新文件。
4,將原文件刪除。
5,將新文件重命名成原文件。
方式一:將硬盤存放的該文件的內容所有加載到內存,在內存中是能夠修改的,修改完畢後,再由內存覆蓋到硬盤(word,vim,nodpad++等編輯器)
import os # 調用系統模塊 with open('測試', encoding='utf-8') as f1,\ open('測試.bak', encoding='utf-8',mode='w') as f2: old_content = f1.read() # 所有讀入內存,若是文件很大,會卡死 new_content = old_content.replace('文', 'wen') # 在內存中完成修改 f2.write(new_content) # 一次性寫入新文件 os.remove('測試') # 刪除原文件 os.rename('測試.bak', '測試') # 將新建的文件重命名爲原文件 # 原文件內容 **文件操做改的流程:** 1,以讀的模式打開原文件。 2,以寫的模式建立一個新文件。 3,將原文件的內容讀出來修改爲新內容,寫入新文件。 4,將原文件刪除。 5,將新文件重命名成原文件。 # 修改後的內容 **wen件操做改的流程:** 1,以讀的模式打開原wen件。 2,以寫的模式建立一個新wen件。 3,將原wen件的內容讀出來修改爲新內容,寫入新wen件。 4,將原wen件刪除。 5,將新wen件重命名成原wen件。
方式二:將硬盤存放的該文件的內容一行一行地讀入內存,修改完畢就寫入新文件,最後用新文件覆蓋源文件(這種是經常使用的)
import os with open('測試', encoding='utf-8') as f1,\ open('測試.bak', encoding='utf-8',mode='w') as f2: for line in f1: # 一行一行的改,佔內存少 new_line = line.replace('wen', '文') f2.write(new_line) os.remove('測試') os.rename('測試.bak', '測試') # 原文件內容 **wen件操做改的流程:** 1,以讀的模式打開原wen件。 2,以寫的模式建立一個新wen件。 3,將原wen件的內容讀出來修改爲新內容,寫入新wen件。 4,將原wen件刪除。 5,將新wen件重命名成原wen件。 # 修改後的內容 **文件操做改的流程:** 1,以讀的模式打開原文件。 2,以寫的模式建立一個新文件。 3,將原文件的內容讀出來修改爲新內容,寫入新文件。 4,將原文件刪除。 5,將新文件重命名成原文件。