一. 基本概念
文件
文件作為數(shù)據(jù)存儲的單位,通常用來長期存儲數(shù)據(jù)。文件中的數(shù)據(jù)是以字節(jié)為單位進(jìn)行順序存儲的。操作文件的操作流程如下:
- 打開文件
- 讀寫文件
- 關(guān)閉文件
注:任何的操作系統(tǒng),同一個應(yīng)用程序同時打開文件的數(shù)量是有最大限制的,所以在用完文件后需要關(guān)閉。
文件的打開函數(shù) open(file, mode='rt') 用于打開一個文件對象,文件打開失敗時觸發(fā)異常;文件的關(guān)閉方法 F.close() 用于關(guān)閉文件,釋放系統(tǒng)資源。
上述 open 函數(shù)中用到了 mode 參數(shù),即文本文件操作模式,對文本文件的讀寫需要用字符串 str 進(jìn)行讀取和寫入數(shù)據(jù)。模式字符:t' 表示默認(rèn)文件中存儲的數(shù)據(jù)為字符數(shù)據(jù),以行為單位分隔。
注: 在 Linux 系統(tǒng)中,換行符為
\n,在 Windows 下?lián)Q行符則為\r\n。在 Python 中內(nèi)部統(tǒng)一用\n作為換行符進(jìn)行分隔:即在文本文件模式下,各操作系統(tǒng)的換行符在讀入 Python 內(nèi)部時,換為字符\n。
實際中常用的文件讀取方式即文件的迭代讀?。?code>open 函數(shù)返回的文件流對象作為可迭代對象,并且是個迭代器:
>> f = open('example.txt')
>> iter(f)
<_io.TextIOWrapper name='example.txt' mode='r' encoding='cp936'>
>> iter(f)
<_io.TextIOWrapper name='example.txt' mode='r' encoding='cp936'>
>> next(f)
'A\n'
>> next(f)
'B\n'
>> next(f)
'C\n'
>> next(f)
StopIteration:
對于二進(jìn)制文件,默認(rèn)文件中存儲的都是以字節(jié)為單位的數(shù)據(jù),通常有人為規(guī)則格式,需要以字節(jié)為單位進(jìn)行讀寫。比如,Linux 下常用的命令 ls 對應(yīng)的二進(jìn)制文件如下:

下面,我們就利用 Python 來讀取該二進(jìn)制文件中的內(nèi)容:
>> f = open('/bin/ls', 'rb')
>> f.read(4)
b'\x7fELF'
>> f.read(1)
b'\x02'
>> f.read(2)
b'\x01\x01'
在以二進(jìn)制讀的形式打開文件 /bin/ls 之后,使用了 read 函數(shù)依次讀取了 4 個字節(jié)、1 個字節(jié)以及 2 個字節(jié)。Python 中關(guān)于文件句柄的方法非常豐富,下面我們就來介紹一下他們吧~
文件句柄的常用方法
關(guān)于文件句柄的常用方法總結(jié)如下:
| 方法名 | 作用 |
|---|---|
read(size) |
讀取 size 個字符,缺省時讀取全部內(nèi)容,并返回一個字符串;每次讀取時在上一次的位置繼續(xù)向下讀,到達(dá)文件末尾則返回空字符串。二進(jìn)制模式下,讀取和返回的都是字節(jié)串。 |
readline() |
讀取 1 行,返回一個字符串;每次讀取一行,到達(dá)文件末尾則返回空字符串。二進(jìn)制模式下,讀取和返回的都是字節(jié)串。 |
readlines() |
每行內(nèi)容作為一個字符串,返回一個列表;二進(jìn)制模式下,返回一個字節(jié)串列表。 |
write(x) |
對于文本模式,X 必須為字符串;對于二進(jìn)制模式,x 必須為字節(jié)串。返回值為寫入的字符數(shù)。 |
writeslines(L) |
按行順序?qū)懭肓斜韮?nèi)的每個元素。 |
關(guān)于 f.read 的返回類型:對于文本模式 t 打開的文件,返回字符串 str ;對于二進(jìn)制模式 b 打開的文件,返回字節(jié)串 bytes 。關(guān)于 f.write(x) 參數(shù) x 的類型:對于文本模式,x 必須為字符串;對于二進(jìn)制模式,x 必須為字節(jié)串。
>> f = open('a.txt', 'wt')
>> f.write('A')
>> f.close()
運行結(jié)果:

>> f = open('b.txt', 'wb')
>> f.write(bytearray([66]))
>> f.close()
運行結(jié)果:

下面是 read readline readlines 的使用示例:
with open('example.txt') as f:
print(f.readline())
print(f.readline())
print(f.readline())
print(f.readline())
運行結(jié)果:

with open('example.txt') as f:
print(f.readlines())
運行結(jié)果:

with open('example.txt') as f:
print(f.read())
運行結(jié)果:

f.seek() 方法用來改變當(dāng)前文件的讀寫位置:f.seek(偏移量, 相對位置) :
- 偏移量:大于 0 的數(shù)代表向文件尾方向移動;小于 0 的數(shù)代表向文件頭方向移動。
- 相對位置:0 代表從文件頭開始偏移;1 代表從當(dāng)前位置開始偏移;2 代表從文件尾開始偏移。
f.tell() 方法返回當(dāng)前文件讀寫位置。
下面是關(guān)于兩方法使用的示例:
with open('example.bin', 'wb') as f:
f.writelines([b'Python\n', b'Hello World\n', b'123456\n'])
文件內(nèi)容如下:

使用 f.seek 和 f.tell:
with open('example.bin', 'rb') as f:
print(f.tell())
print(f.read(6))
print(f.tell())
print(f.seek(7, 1))
print(f.read(5))
print(f.seek(-7, 2))
print(f.read(7))
運行結(jié)果:

通常,二進(jìn)制文件會用到 seek 和 tell 。
二. 漢字編碼
漢字常用的 2 種編碼方式即國標(biāo)系列和國際標(biāo)準(zhǔn)。其中國標(biāo)系列即 Windows 常用的編碼方式:
- GB18030 (二字節(jié)或四字節(jié)編碼,共27533個漢字)相比 GBK 多出的部分使用的是四字節(jié)編碼
- GBK(二字節(jié)編碼,共21003個漢字)
- GB2312(二字節(jié)編碼,共6763個漢字)
國際標(biāo)準(zhǔn)則用于 Linux、Mac OS X、IOS、Android 等系統(tǒng),如:UNICODE 16、UNICODE 31 等。
注:Python3 的字符串存儲的是 Unicode 編碼,但要存儲在外部(磁盤,網(wǎng)絡(luò)等)的時候,需要
encode編碼。
Python 編碼(encode)字符串:gb2312 gbk gb18030 utf-8 ascii。
注:在 Python 源文件第一行或第二行寫入如下內(nèi)容即告訴解釋執(zhí)行器,此文件的編碼類型是什么,如:
# -*- coding: gbk -*-設(shè)置源文件編碼格式為 GBK ;# -*- coding: utf-8 -*-設(shè)置源文件編碼格式為utf-8。Python3 源文件默認(rèn)使用的編碼方式即utf-8。
三. 總結(jié)
各類模式:
| 符號 | 含義 |
|---|---|
t |
以文本模式打開,是默認(rèn)的文件打開方式; |
b |
二進(jìn)制模式打開; |
r |
以只讀的形式打開,是默認(rèn)的打開方式; |
w |
以寫的方式打開,會刪除文件中原有的內(nèi)容; |
a |
以追加的方式打開文件,原有內(nèi)容不會刪除; |
x |
創(chuàng)建新文件,文件已存在時,將觸發(fā)異常; |
文本文件操作模式:
- 默認(rèn)文件中存儲的數(shù)據(jù)為字符數(shù)據(jù),以行為單位分隔,在 Python 中內(nèi)部統(tǒng)一用
\n作為換行符進(jìn)行分隔; - 對文本文件的讀寫需要用字符串
str進(jìn)行讀取和寫入數(shù)據(jù)。
二進(jìn)制文件操作模式:
- 默認(rèn)文件中存儲的都是以字節(jié)為單位的數(shù)據(jù),通常有人為規(guī)則格式;
- 需要以字節(jié)為單位進(jìn)行讀寫
open() 函數(shù):
open(file, mode='rt') 用于打開一個文件對象,如果打開文件失敗,則會觸發(fā) OSError;
open() 函數(shù)返回一個表示文件的對象,可作為迭代器;結(jié)合 next() 函數(shù)使用,每次返回一行內(nèi)容,停止迭代時觸發(fā) StopIteration 。