python file文件操作--內置對象open


說明:

  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()

  運行前文件內容:

   

   運行后文件內容:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM