說明:
1. 函數功能打開一個文件,返回一個文件讀寫對象,然后可以對文件進行相應讀寫操作。
2. file參數表示的需要打開文件的相對路徑(當前工作目錄)或者一個絕對路徑,當傳入路徑不存在此文件會報錯。或者傳入文件的句柄。
>>> a = open('test.txt') # 相對路徑 >>> a <_io.TextIOWrapper name='test.txt' mode='r' encoding='cp936'> >>> a.close() >>> a = open(r'D:\Python\Python35-32\test.txt') # 絕對路徑 >>> a <_io.TextIOWrapper name='D:\\Python\\Python35-32\\test.txt' mode='r' encoding='cp936'>
3. mode參數表示打開文件的模式,常見的打開模式有如下幾種,實際調用的時候可以根據情況進行組合。
打開文件時,需要指定文件路徑和以何等方式打開文件,打開后,即可獲取該文件句柄,日后通過此文件句柄對該文件操作。
打開文件的模式有:
- r ,只讀模式【默認】
- w,只寫模式【不可讀;不存在則創建;存在則清空內容;】
- x, 只寫模式【不可讀;不存在則創建,存在則報錯】
- a, 追加模式【可讀; 不存在則創建;存在則只追加內容;】
"+" 表示可以同時讀寫某個文件
- r+, 讀寫【可讀,可寫】
- w+,寫讀【可讀,可寫】
- x+ ,寫讀【可讀,可寫】
- a+, 寫讀【可讀,可寫】
"b"表示以字節的方式操作
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型
t為文本讀寫,b為二進制讀寫
# t為文本讀寫,b為二進制讀寫 >>> a = open('test.txt','rt') >>> a.read() 'some text' >>> a = open('test.txt','rb') >>> a.read() b'some text' # r為只讀,不能寫入;w為只寫,不能讀取 >>> a = open('test.txt','rt') >>> a.write('more text') Traceback (most recent call last): File "<pyshell#67>", line 1, in <module> a.write('more text') io.UnsupportedOperation: write >>> a = open('test.txt','wt') >>> a.read() Traceback (most recent call last): File "<pyshell#69>", line 1, in <module> a.read() io.UnsupportedOperation: not readable #其它不一一舉例了
4. buffering表示文件在讀取操作時使用的緩沖策略。
0: 代表buffer關閉(只適用於二進制模式)
1: 代表line buffer(只適用於文本模式)
>1: 表示初始化的buffer大小
5. encoding參數表示讀寫文件時所使用的的文件編碼格式。
假設現在test.txt文件以utf-8編碼存儲了一下文本:
>>> a = open('test.txt','rt') # 未正確指定編碼,有可能報錯 >>> a.read() Traceback (most recent call last): File "<pyshell#87>", line 1, in <module> a.read() UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 8: illegal multibyte sequence >>> a = open('test.txt','rt',encoding = 'utf-8') >>> a.read() '我是第1行文本,我將被顯示在屏幕\n我是第2行文本,我將被顯示在屏幕\n我是第3行文本,我將被顯示在屏幕' >>>
6. errors參數表示讀寫文件時碰到錯誤的報錯級別。
常見的報錯基本有:
'strict'
嚴格級別,字符編碼有報錯即拋出異常,也是默認的級別,errors參數值傳入None按此級別處理.'ignore'
忽略級別,字符編碼有錯,忽略掉.'replace'
替換級別,字符編碼有錯的,替換成?.
>>> a = open('test.txt','rt',encoding = 'utf-8') >>> a.read() '我是第1行文本,我將被顯示在屏幕\n我是第2行文本,我將被顯示在屏幕\n我是第3行文本,我將被顯示在屏幕' >>> a = open('test.txt','rt') >>> a.read() Traceback (most recent call last): File "<pyshell#91>", line 1, in <module> a.read() UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 8: illegal multibyte sequence >>> a = open('test.txt','rt',errors = 'ignore' ) >>> a.read() >>> a = open('test.txt','rt',errors = 'replace' ) >>> a.read()
7. newline表示用於區分換行符(只對文本模式有效,可以取的值有None,'\n','\r','','\r\n')
>>> a = open('test.txt','rt',encoding = 'utf-8',newline = '\r') >>> a.readline() '我是第1行文本,我將被顯示在屏幕\r' >>> a = open('test.txt','rt',encoding = 'utf-8',newline = '\n') >>> a.readline() '我是第1行文本,我將被顯示在屏幕\r\n'
8. closefd表示傳入的file參數類型(缺省為True),傳入文件路徑時一定為True,傳入文件句柄則為False。
>>> a = open('test.txt','rt',encoding = 'utf-8',newline = '\n',closefd = False) Traceback (most recent call last): File "<pyshell#115>", line 1, in <module> a = open('test.txt','rt',encoding = 'utf-8',newline = '\n',closefd = False) ValueError: Cannot use closefd=False with file name >>> a = open('test.txt','rt',encoding = 'utf-8',newline = '\n',closefd = True)
筆記總結:
a) 以二進制方式讀寫文件
python3 提供了一種機制, 以字節(二進制)的方式打開
1 #二進制方式寫入文件 2 f = open("d:/data.txt", "wb") 3 str = "卧室麗1" 4 #需要將字符串轉換為二進制以后才能添加 5 f.write(bytes(str,encoding="utf-8")) 6 f.close() 7 8 9 #二進制方式讀取文件 10 f = open("d:/data.txt", "rb") 11 str = f.read() 12 f.close() 13 print(str)
輸出結果:
卧室麗1
b'\xe5\x8d\xa7\xe5\xae\xa4\xe7\xbd\x97\xe6\x99\x93\xe4\xb8\xbd1'
b) r+, w+, x+, a+ 四種模式都是可讀可寫, 那么他們的區別是什么?
想了解區別, 首先知道file的四個方法: 1. read(): 讀數據, 2.write(): 寫數據, 3.tell(): 獲取當前指針的位置, 4.seek(): 重置指針的位置.
r+ 讀寫文件
-
-
- 從開始像后讀
- 寫, 以追加的方式寫, 指針指向最后
-
1 print("-------- r+: 從頭讀取, 寫入后指針指向最后 -------------") 2 #r+: 讀的時候從開始向后讀數據, 3 # 寫的時候是在末尾追加, 指針指向末尾 4 f = open("d:/data.txt", "r+",encoding="utf-8") 5 #tell 獲取指針位置,位置是0 6 print(f.tell()) 7 #指定讀取3個字符, 一個漢字三個字節 8 str = f.read(3) 9 #此時指針已經在第9個字節的位置了 10 print(f.tell()) 11 print(str) 12 #再次讀取6個字符, 那么指針應該指向9+18=27的位置了 13 str = f.read(6) 14 # 指針指向第27個字符 15 print(f.tell()) 16 print(str) 17 18 #此時, 在寫, 寫完之后看看指針在哪里? 19 f.write("SSSBBB") 20 # 指針指向最后了 21 print(f.tell()) 22 # 由此可見, 讀的時候可以調整指針, 但是寫的時候指針都是調整到最后去寫. 23 24 f.close()
執行結果:
1 -------- r+: 從頭讀取, 寫入后指針指向最后 ------------- 2 0 3 9 4 美麗麗 5 20 6 卧室麗1 7 8 26
注意: 如果在文件打開后就寫入, 則會寫在開始,並覆蓋指定字符數. 因為以r+方式打開, 指針指向文件最開始. 注意分析一下代碼:
1 print("======= 測試r+模式write數據指針的位置變化 =====") 2 3 #先清空再寫入數據 4 f = open("data.txt","r+",encoding="utf-8") 5 content = "你是誰,我也不知道,啊啊啊啊啊" 6 print("文件內容: ", content) 7 8 str = f.write(content) 9 f.close() 10 11 print("--------------") 12 13 14 15 #以r+的方式open數據, open后指針在文件的最開始, 這個時候write數據, 16 # 會從最開始插入數據,並替換原來的字節數 17 f = open("data.txt", "r+", encoding="utf-8") 18 print("文件打開后, 指針位置: ", f.tell()) 19 f.write("aaaaaa") 20 print("寫入aaaaaa后, 指針位置: ",f.tell()) 21 22 str = f.read(3) 23 print("讀取三個字符后, 指針位置: ",f.tell()) 24 print("讀取三個字符內容: ",str) 25 #在中間的位置write數據, 則追加到最后. 26 f.write("bbbb") 27 print("再次寫入bbbb內容后, 指針位置: ",f.tell()) 28 f.close()
執行結果:
1 ======= 測試r+模式write數據指針的位置變化 ===== 2 文件內容: 你是誰,我也不知道,啊啊啊啊啊 3 -------------- 4 文件打開后, 指針位置: 0 5 寫入aaaaaa后, 指針位置: 6 6 讀取三個字符后, 指針位置: 13 7 讀取三個字符內容: 誰,我 8 再次寫入bbbb內容后, 指針位置: 65
w+ 讀寫文件
-
-
- 最重要的特征, 先清空, 然后讀寫. 也就是先把文件內容清空, 然后讀寫.
- 讀的時候, 從前往后讀,
- 寫完以后, 指針指向末尾
-
1 print("========== #w+ ===========") 2 #w+ : 3 # 先清空, 在寫讀. 4 # 先寫, 后讀. 5 # 寫后指針指向末尾 6 f = open("d:/data.txt", "w+",encoding="utf-8") 7 data = f.read() 8 print("data:"+data) 9 f.write("美麗麗") 10 # 寫完之后直接讀, 讀不到內容, 因為寫完以后指針已經知道最后了 11 data = f.read() 12 print("after write:"+data) 13 # 使用seek重新讓指針指向0 14 f.seek(0) 15 data = f.read() 16 print(data) 17 f.close()
執行結果:
1 ========== #w+ =========== 2 data: 3 after write: 4 美麗麗
x+ 與 w+ 的區別:
#x+: x+和w+一樣, 只是額外的存在一個功能, 那就是文件存在則報錯.
a+ 讀寫文件
-
-
- 最重要的特征,讀取文件以后, 指針指向最后, .
- 讀的時候, 從前往后讀,
- 寫完以后, 指針指向末尾
-
print("-------------a+: 打開文件,執行指向最后, 調整指針位置讀取--------------") #a+: 可以讀可以寫 f = open("d:/data.txt", "a+", encoding="utf-8") #當前指針指向位置, 使用a+的方式, 打開的同時指針已經在最后的位置 print(f.tell()) #讀取三個字節, 讀取內容為空, 因為指針指向最后 str = f.read(1) #讀取3個字符后指針的位置 print(f.tell()) #重新將指針指向開始 f.seek(0) #讀取指針的位置 print(f.tell()) # 讀取一個字符 str= f.read(1) # 一個字符后,指針的位置 print(f.tell()) print(str) f.close()
文件操作常用方法
1. close 關閉文件.
python2.6 以后有一個with語句. 可以自動關閉文件.不用手動關閉
1 #with自動關閉打開的file.無需手動調用close()方法 2 with open("data.txt","r",encoding="utf-8") as f: 3 str = f.readline() 4 print(str) 5 6 # with 還可以同時打開兩個文件. 可以用於文件拷貝. 例如:將文件1的內容拷貝到文件2 7 with open("data.txt" ,"r", encoding="utf-8") as f1, open("data1.txt", "w", encoding="utf-8") as f2: 8 #讀取文件1的每一行數據, 寫入到文件2 9 for line in f1: 10 f2.write(line)
2. flush 將文件從緩沖區刷新到硬盤
write到file的內部,在進程沒有結束之前, 都是保存在內存中, 通過flush方法可以將文件刷到硬盤上
1 f = open("data.txt","r+",encoding="utf-8") 2 f.write("再次添加內容2") 3 # 手動調用flush方法,將write的內容刷入硬盤 4 #f.flush() 5 str = input("請輸入:") 6 7 #在執行到input時, 進程沒有結束, 文件write的內容保存在內存中, 並沒有保存在硬盤上. 8 # 放開 f.flush(),手動刷新內存中的文件到硬盤上
將文件輸入到硬盤有三種方法
- 1. 手動調用close()方法
- 2. 進程結束, 自動刷新內存中內容到硬盤
- 3. 手動調用flush()方法, 手動刷新內存中內容到硬盤
1 print("===== flush 刷新文件內部緩沖區 =======") 2 3 #1. 手動調用close()方法 4 f = open("data.txt","w",encoding="utf-8") 5 f.write("新添加的內容") 6 # 執行f.close()后,會自動調用flush將write的內容寫進硬盤. 7 f.close() 8 9 10 11 # 2. 進程結束, 自動刷新內存中內容到硬盤 12 f = open("data.txt","r+",encoding="utf-8") 13 f.write("再次添加內容1") 14 # 進程結束, 也會自動將write的內容刷如硬盤 15 16 17 18 # 3. 手動調用flush()方法, 手動刷新內存中內容到硬盤 19 f = open("data.txt","r+",encoding="utf-8") 20 f.write("再次添加內容2") 21 # 手動調用flush方法,將write的內容刷入硬盤 22 f.flush() 23 str = input("請輸入:")
truncate: 截斷數據,僅保留指定之前數據
1 # truncate: 截斷數據,僅保留指定之前數據 2 f = open("data1.txt", "r+", encoding="utf-8") 3 #f.seek(5) 4 # 一個參數, 指定保留字符個數 5 f.truncate(20) 6 # f.flush() 7 f.seek(0) 8 str = f.read() 9 print(str) 10 f.close()
運行前文件內容:
運行后文件內容: