如果以 r+、w、w+、a、a+ 模式打開文件,則都可以寫入。需要指出的是,當以 r+、w、w+ 模式打開文件時,文件指針位于文件開頭處;當以 a、a+ 模式打開文件時,文件指針位于文件結尾處。
另外,需要說明的是,當以 w 或 w+ 模式打開文件時,程序會立即清空文件的內容。
文件指針的概念
文件指針用于標明文件讀寫的位置。假如把文件看成一個水流,文件中每個數(shù)據(jù)(以 b 模式打開,每個數(shù)據(jù)就是一個字節(jié);以普通模式打開,每個數(shù)據(jù)就是一個字符)就相當于一個水滴,而文件指針就標明了文件將要讀寫哪個位置。
圖 1 簡單示意了文件指針的概念。
圖 1 文件指針概念示意圖
文件對象提供了以下方法來操作文件指針:
-
seek(offset[, whence]):該方法把文件指針移動到指定位置。當 whence 為 0 時(這是默認值),表明從文件開頭開始計算,比如將 offset 設為 3,就是將文件指針移動到第 3 處;當 whence 為 1 時,表明從指針當前位置開始計算,比如文件指針當前在第 5 處,將 offset 設為 3,就是將文件指針移動到第 8 處;當 whence 為 2 時,表明從文件結尾開始計算,比如將 offset 設為 3,表明將文件指針移動到文件結尾倒數(shù)第 3 處。
-
tell():判斷文件指針的位置。
此外,當程序使用文件對象讀寫數(shù)據(jù)時,文件指針會自動向后移動:讀寫了多少個數(shù)據(jù),文件指針就自動向后移動多少個位置。
下面程序示范了文件指針操作:
- f = open('filept_test.py', 'rb')
- # 判斷文件指針的位置
- print(f.tell()) # 0
- # 將文件指針移動到3處
- f.seek(3)
- print(f.tell()) # 3
- # 讀取一個字節(jié),文件指針自動后移1個數(shù)據(jù)
- print(f.read(1)) # o
- print(f.tell()) # 4
- # 將文件指針移動到5處
- f.seek(5)
- print(f.tell()) # 5
- # 將文件指針向后移動5個數(shù)據(jù)
- f.seek(5, 1)
- print(f.tell()) # 10
- # 將文件指針移動到倒數(shù)第10處
- f.seek(-10, 2)
- print(f.tell())
- print(f.read(1)) # d
上面程序示范了使用 seek() 方法來移動文件指針,包括從文件開頭、指針當前位置、文件結尾處開始計算。運行上面程序,結合程序輸出結果可以體會文件指針移動的效果。
當文件指針位于哪里時,程序就會讀取哪個位置的數(shù)據(jù);當程序讀取多少個數(shù)據(jù)時,文件指針就會自動向后移動多少個位置。
輸出內容
文件對象提供的寫文件的方法主要有兩個:
-
write(str 或 bytes):輸出字符串或字節(jié)串。只有以二進制模式(b 模式)打開的文件才能寫入字節(jié)串。
-
writelines(可迭代對象):輸出多個字符串或多個字節(jié)串。
下面程序示范了使用 write() 和 writelines() 輸出字符串:
- import os
- f = open('x.txt', 'w+')
- # os.linesep代表當前操作系統(tǒng)上的換行符
- f.write('我愛Python' + os.linesep)
- f.writelines(('土門壁甚堅,'+ os.linesep,
- '杏園度亦難。'+ os.linesep,
- '勢異鄴城下,'+ os.linesep,
- '縱死時猶寬。'+ os.linesep))
上面程序中第 4 行代碼調用 write() 方法輸出單個字符串;第 5 行代碼則調用 writelines() 方法輸出多個字符串。
當采用上面方法輸出文件時,程序會使用當前操作系統(tǒng)默認的字符集。如果需要使用指定的字符集來輸出文件,則可以來用二進制形式(程序先將所輸出的字符串轉換成指定字符集對應的二進制數(shù)據(jù)(字節(jié)串),然后輸出二進制數(shù)據(jù))。
下面程序示范了使用二進制數(shù)據(jù)輸出,通過這種方式來實現(xiàn)以 UTF-8 字符集保存文件:
- import os
- f = open('y.txt', 'wb+')
- # os.linesep代表當前操作系統(tǒng)上的換行符
- f.write(('我愛Python' + os.linesep).encode('utf-8'))
- f.writelines((('土門壁甚堅,'+ os.linesep).encode('utf-8'),
- ('杏園度亦難。'+ os.linesep).encode('utf-8'),
- ('勢異鄴城下,'+ os.linesep).encode('utf-8'),
- ('縱死時猶寬。'+ os.linesep).encode('utf-8')))
上面程序中的代碼以 wb+ 模式打開文件,這意味著程序會以二進制形式來輸出文件,此時程序輸出的必須是宇節(jié)串,不能是字符串。因此,程序調用 encode() 方法將字符串轉換成字節(jié)串,轉換時指定使用 UTF-8 字符集,這意味著程序將會以 UTF-8 字符集來保存文件。
該程序輸出的文件內容與上一個程序輸出的文件內容相同,只是該程序輸出的文件內容是以 UTF-8 字符集保存的。
從上面的程序可以看到,當使用 w+、wb+ 模式打開文件時,會導致文件內容被清空。因此,無論程序運行多少次,其輸出的文件內容都只保留最近一次的輸出數(shù)據(jù)。如果程序希望在文件后面追加內容,則應該使用 a+ 或 ab+ 模式。例如如下程序:
- import os
- f = open('z.txt', 'a+')
- # os.linesep代表當前操作系統(tǒng)上的換行符
- f.write('我愛Python' + os.linesep)
- f.writelines(('土門壁甚堅,'+ os.linesep,
- '杏園度亦難。'+ os.linesep,
- '勢異鄴城下,'+ os.linesep,
- '縱死時猶寬。'+ os.linesep))
上面程序以 a+ 模式打開指定文件,這意味著以追加模式來打開文件,因此,使用 open() 函數(shù)打開文件后,不會立即清空文件內容,并且會將文件指針移動到文件結尾處,程序會在文件結尾處追加內容。
每次運行上面程序,都會向 z.txt 文件中追加一段內容;程序運行的次數(shù)越多,z.txt 文件的內容就會越多。
|