Python 中的文件 IO 操作
1. 打開(kāi)和關(guān)閉文件
1.1 打開(kāi)文件
訪(fǎng)問(wèn)文件前,需要使用用 Python 內(nèi)置的 open() 函數(shù)打開(kāi)一個(gè)文件:
open(path, access_mode)
- path 是要訪(fǎng)問(wèn)的文件的路徑名
- access_mode 是文件的訪(fǎng)問(wèn)模式
- 可以是只讀、讀寫(xiě)、追加等模式,所有可能的取值見(jiàn) 1.2 小節(jié)
- 這個(gè)參數(shù)是可選的,缺省情況下,是以只讀模式 r 打開(kāi)文件
- open 返回一個(gè) file 對(duì)象,通過(guò)調(diào)用 file 對(duì)象的成員方法訪(fǎng)問(wèn)該文件
使用 open 打開(kāi)一個(gè)文件并訪(fǎng)問(wèn):
file = open('test.txt')
line = file.readline()
print(line)
- 在第 1 行,以只讀方式打開(kāi)文件 test.txt,open 返回一個(gè) file 對(duì)象
- 在第 2 行,調(diào)用 file 對(duì)象的 readline() 方法從文件中讀取一行
1.2 文件的訪(fǎng)問(wèn)模式
下表列出了常用的文件訪(fǎng)問(wèn)模式:
模式 | 描述 | 如果文件存在 | 如果文件不存在 |
---|---|---|---|
r | 以只讀方式打開(kāi)文件 | 保留原有內(nèi)容,從文件頭部開(kāi)始讀 | 拋出異常 FileNotFoundError |
r+ | 以讀寫(xiě)方式打開(kāi)文件 | 保留原有內(nèi)容,從文件頭部開(kāi)始讀 | 拋出異常 FileNotFoundError |
w | 以只寫(xiě)方式打開(kāi)文件 | 刪除原有內(nèi)容,從文件頭部開(kāi)始寫(xiě)入 | 創(chuàng)建新文件 |
w+ | 以讀寫(xiě)方式打開(kāi)文件 | 刪除原有內(nèi)容,從文件頭部開(kāi)始讀寫(xiě) | 創(chuàng)建新文件 |
a | 以只寫(xiě)方式打開(kāi)文件 | 保留原有內(nèi)容,從文件尾部開(kāi)始讀寫(xiě) | 創(chuàng)建新文件 |
a+ | 以讀寫(xiě)方式打開(kāi)文件 | 保留原有內(nèi)容,從文件尾部開(kāi)始讀寫(xiě) | 創(chuàng)建新文件 |
1.3 關(guān)閉文件
訪(fǎng)問(wèn)文件的步驟如下:
- 打開(kāi)文件
- 讀寫(xiě)文件
- 關(guān)閉文件
當(dāng)文件訪(fǎng)問(wèn)完畢后,不再需要訪(fǎng)問(wèn)該文件時(shí),需要及時(shí)的調(diào)用 file 對(duì)象的 close() 方法關(guān)閉文件。以下是及時(shí)關(guān)閉文件的例子:
file = open('test.txt')
file.read()
file.close()
2. 文件對(duì)象
open 返回一個(gè) file 對(duì)象,通過(guò)調(diào)用 file 對(duì)象的成員方法訪(fǎng)問(wèn)該文件,下表總結(jié)了 file 對(duì)象的成員方法。
成員方法 | 功能 |
---|---|
close() | 關(guān)閉文件,關(guān)閉之后便不能再進(jìn)行寫(xiě)入 |
write(string) | 將字符串 string 寫(xiě)入文件 |
read(count) | 從文件中讀取一個(gè)字符串,至多讀取 count 個(gè)字符 |
tell() | 獲取文件的當(dāng)前訪(fǎng)問(wèn)位置 |
seek(offset, from) | 改變文件的當(dāng)前訪(fǎng)問(wèn)位置 |
seek(offset, from) 的功能是根據(jù)參數(shù) offset 和 from 改變當(dāng)前文件的訪(fǎng)問(wèn)位置:
- 參數(shù) offset 表示要移動(dòng)的字節(jié)數(shù)
- 參數(shù) from 指定開(kāi)始移動(dòng)字節(jié)的參考位置
- 如果 from 被設(shè)為 0,將文件的開(kāi)頭作為移動(dòng)的參考位置
- 如果 from 被設(shè)為 1,將文件的當(dāng)前訪(fǎng)問(wèn)位置作為移動(dòng)的參考位置
- 如果 from 被設(shè)為 2,將文件的末尾作為移動(dòng)的參考位置
3. 應(yīng)用場(chǎng)景
3.1 使用 while 循環(huán)打印文件的每行
假設(shè)文件 test.txt 的內(nèi)容:
www
imooc
com
下面使用 readline() 方讀取文件的每行并打印:
file = open('test.txt')
while True:
line = file.readline()
if line == '':
break
print(line, end = '')
file.close()
- 在第 1 行,以只讀方式打開(kāi)文件 test.txt
- 在第 3 行,調(diào)用 readline() 方法讀取文件的一行,讀取的數(shù)據(jù)包括換行
- 在第 4 行,如果讀取到文件尾部,則返回一個(gè)空字符串,此時(shí)退出循環(huán)
- 在第 6 行,缺省情況下 print 輸出時(shí)會(huì)自動(dòng)加上換行,因?yàn)?readline() 返回的數(shù)據(jù)會(huì)包含換行,因此使用命名參數(shù) end = ‘’ 使 print 輸出時(shí)不換行
運(yùn)行程序,程序輸出如下:
www
imooc
com
3.2 使用 for 循環(huán)打印文件的每行
Python 中的 file 對(duì)象是一個(gè)可迭代對(duì)象 Iterable,可以使用 for 循環(huán)遍歷 file 對(duì)象。for 循環(huán)遍歷文件的每一行,示例如下:
file = open('test.txt')
for line in file:
print(line, end = '')
file.close()
- 在第 2 行,使用 for 循環(huán)遍歷文件 file 的每一行
- line 指向當(dāng)前遍歷的行,包括換行符
- 在第 4 行, 因?yàn)?line 包含換行符,因此使用命名參數(shù) end = ‘’ 使 print 輸出時(shí)不換行
3.3 復(fù)制文件
下面的例子實(shí)現(xiàn)復(fù)制文件的功能:
def copy(src_path, dst_path):
src_file = open(src_path, 'r')
dst_file = open(dst_path, 'w')
for line in src_file:
dst_file.write(line)
src_file.close()
dst_file.close()
copy('test.txt', 'test.bak')
- 在第 2 行,以只讀方式打開(kāi)源文件 src_path
- 在第 3 行,以只寫(xiě)方式打開(kāi)目標(biāo)文件 dst_path
- 在第 4 行,遍歷源文件 src_file 的每一行 line
- 在第 5 行,將 line 寫(xiě)入到目標(biāo)文件 dst_file
- 在第 6 行,及時(shí)關(guān)閉 src_file 和 dst_file
3.4 向文件追加內(nèi)容
編寫(xiě)一個(gè)用于記錄日志的函數(shù) log(msg),該函數(shù)將 msg 寫(xiě)入到日志文件 log.txt 中。每次寫(xiě)日志文件時(shí),需要:
- 保留日志文件的原有內(nèi)容
- 將新的記錄添加到日志文件的尾部
文件 log.py 的內(nèi)容如下:
from datetime import datetime
def log(msg):
dt = datetime.today()
now = dt.strftime("%Y-%m-%d %H:%M:%S")
line = '%s: %s\n' % (now, msg)
log_file.write(line)
log_file = open('log.txt', 'a')
log('hello')
log('world')
log_file.close()
- 在第 3 行,編寫(xiě)函數(shù) log(msg),用于將 msg 追加到日志文件 log.txt
- 在第 4 行到第 5 行,獲取當(dāng)前時(shí)間 now
- 在第 6 行,將當(dāng)前時(shí)間 now 和信息 msg 追加到日志文件
- 在第 9 行,以追加模式 a 打開(kāi)文件 log.txt
- 向文件寫(xiě)數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)被追加到文件尾部
- 在第 10 行,向日志中寫(xiě)入 hello
- 在第 11 行,向日志中寫(xiě)入 world
- 在第 12 行,關(guān)閉日志文件
運(yùn)行 log.py,命令如下:
C:\> python log.py
C:\> dir
2020/06/04 11:47 <DIR> .
2020/06/04 11:47 <DIR> ..
2020/06/04 11:49 249 log.py
2020/06/04 11:50 56 log.txt
- 在第 6 行,顯示當(dāng)前目錄下存在文件 log.txt
- 以追加模式 a 打開(kāi)文件 log.txt,如果文件不存在則創(chuàng)建文件
此時(shí)文件 log.txt 的內(nèi)容如下,文件中包含有兩行文本:
2020-06-04 11:49:54: hello
2020-06-04 11:49:54: world
再次運(yùn)行程序 log.py,命令如下:
C:\> python log.py
此時(shí)文件 log.txt 的內(nèi)容如下,文件中包含有四行文本:
2020-06-04 11:49:54: hello
2020-06-04 11:49:54: world
2020-06-04 11:50:06: hello
2020-06-04 11:50:06: world