Python3-文件讀寫(xiě)

讀寫(xiě)文件是最常見(jiàn)的IO操作驻售。Python內(nèi)置了讀寫(xiě)文件的函數(shù)介评,用法和C是兼容的矢空。

讀寫(xiě)文件前航罗,我們先必須了解一下,在磁盤上讀寫(xiě)文件的功能都是由操作系統(tǒng)提供的屁药,現(xiàn)代操作系統(tǒng)不允許普通的程序直接操作磁盤粥血,所以,讀寫(xiě)文件就是請(qǐng)求操作系統(tǒng)打開(kāi)一個(gè)文件對(duì)象(通常稱為文件描述符)酿箭,然后复亏,通過(guò)操作系統(tǒng)提供的接口從這個(gè)文件對(duì)象中讀取數(shù)據(jù)(讀文件),或者把數(shù)據(jù)寫(xiě)入這個(gè)文件對(duì)象(寫(xiě)文件)缭嫡。

讀文件

要以讀文件的模式打開(kāi)一個(gè)文件對(duì)象缔御,使用Python內(nèi)置的open()函數(shù),傳入文件名和標(biāo)示符:

>>> f = open('/Users/michael/test.txt', 'r')

標(biāo)示符'r'表示讀妇蛀,這樣耕突,我們就成功地打開(kāi)了一個(gè)文件。

如果文件不存在评架,open()函數(shù)就會(huì)拋出一個(gè)IOError的錯(cuò)誤眷茁,并且給出錯(cuò)誤碼和詳細(xì)的信息告訴你文件不存在:

>>> f=open('/Users/michael/notfound.txt', 'r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/notfound.txt'

如果文件打開(kāi)成功,接下來(lái)纵诞,調(diào)用read()方法可以一次讀取文件的全部?jī)?nèi)容上祈,Python把內(nèi)容讀到內(nèi)存,用一個(gè)str對(duì)象表示:

>>> f.read()
'Hello, world!'

最后一步是調(diào)用close()方法關(guān)閉文件。文件使用完畢后必須關(guān)閉雇逞,因?yàn)槲募?duì)象會(huì)占用操作系統(tǒng)的資源,并且操作系統(tǒng)同一時(shí)間能打開(kāi)的文件數(shù)量也是有限的:

>>> f.close()

由于文件讀寫(xiě)時(shí)都有可能產(chǎn)生IOError茁裙,一旦出錯(cuò)塘砸,后面的f.close()就不會(huì)調(diào)用。所以晤锥,為了保證無(wú)論是否出錯(cuò)都能正確地關(guān)閉文件掉蔬,我們可以使用try ... finally來(lái)實(shí)現(xiàn):

try:
    f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()

但是每次都這么寫(xiě)實(shí)在太繁瑣,所以矾瘾,Python引入了with語(yǔ)句來(lái)自動(dòng)幫我們調(diào)用close()方法:

with open('/path/to/file', 'r') as f:
    print(f.read())

這和前面的try ... finally是一樣的女轿,但是代碼更佳簡(jiǎn)潔,并且不必調(diào)用f.close()方法壕翩。

調(diào)用read()會(huì)一次性讀取文件的全部?jī)?nèi)容蛉迹,如果文件有10G,內(nèi)存就爆了放妈,所以北救,要保險(xiǎn)起見(jiàn),可以反復(fù)調(diào)用read(size)方法芜抒,每次最多讀取size個(gè)字節(jié)的內(nèi)容珍策。另外,調(diào)用readline()可以每次讀取一行內(nèi)容宅倒,調(diào)用readlines()一次讀取所有內(nèi)容并按行返回list攘宙。因此,要根據(jù)需要決定怎么調(diào)用拐迁。

如果文件很小蹭劈,read()一次性讀取最方便;如果不能確定文件大小唠亚,反復(fù)調(diào)用read(size)比較保險(xiǎn)链方;如果是配置文件,調(diào)用readlines()最方便:

for line in f.readlines():
    print(line.strip()) # 把末尾的'\n'刪掉

file-like Object

open()函數(shù)返回的這種有個(gè)read()方法的對(duì)象灶搜,在Python中統(tǒng)稱為file-like Object祟蚀。除了file外,還可以是內(nèi)存的字節(jié)流割卖,網(wǎng)絡(luò)流前酿,自定義流等等。file-like Object不要求從特定類繼承鹏溯,只要寫(xiě)個(gè)read()方法就行罢维。

StringIO就是在內(nèi)存中創(chuàng)建的file-like Object,常用作臨時(shí)緩沖丙挽。

二進(jìn)制文件

前面講的默認(rèn)都是讀取文本文件肺孵,并且是UTF-8編碼的文本文件匀借。要讀取二進(jìn)制文件,比如圖片平窘、視頻等等吓肋,用'rb'模式打開(kāi)文件即可:

>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六進(jìn)制表示的字節(jié)

字符編碼

要讀取非UTF-8編碼的文本文件,需要給open()函數(shù)傳入encoding參數(shù)瑰艘,例如是鬼,讀取GBK編碼的文件:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
>>> f.read()
'測(cè)試'

遇到有些編碼不規(guī)范的文件,你可能會(huì)遇到UnicodeDecodeError紫新,因?yàn)樵谖谋疚募锌赡軍A雜了一些非法編碼的字符均蜜。遇到這種情況,open()函數(shù)還接收一個(gè)errors參數(shù)芒率,表示如果遇到編碼錯(cuò)誤后如何處理囤耳。最簡(jiǎn)單的方式是直接忽略:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

寫(xiě)文件

寫(xiě)文件和讀文件是一樣的,唯一區(qū)別是調(diào)用open()函數(shù)時(shí)敲董,傳入標(biāo)識(shí)符'w'或者'wb'表示寫(xiě)文本文件或?qū)懚M(jìn)制文件:

>>> f = open('/Users/michael/test.txt', 'w')
>>> f.write('Hello, world!')
>>> f.close()

你可以反復(fù)調(diào)用write()來(lái)寫(xiě)入文件紫皇,但是務(wù)必要調(diào)用f.close()來(lái)關(guān)閉文件。當(dāng)我們寫(xiě)文件時(shí)腋寨,操作系統(tǒng)往往不會(huì)立刻把數(shù)據(jù)寫(xiě)入磁盤聪铺,而是放到內(nèi)存緩存起來(lái),空閑的時(shí)候再慢慢寫(xiě)入萄窜。只有調(diào)用close()方法時(shí)铃剔,操作系統(tǒng)才保證把沒(méi)有寫(xiě)入的數(shù)據(jù)全部寫(xiě)入磁盤。忘記調(diào)用close()的后果是數(shù)據(jù)可能只寫(xiě)了一部分到磁盤查刻,剩下的丟失了键兜。所以,還是用with語(yǔ)句來(lái)得保險(xiǎn):

with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

要寫(xiě)入特定編碼的文本文件穗泵,請(qǐng)給open()函數(shù)傳入encoding參數(shù)普气,將字符串自動(dòng)轉(zhuǎn)換成指定編碼。

細(xì)心的童鞋會(huì)發(fā)現(xiàn)佃延,以'w'模式寫(xiě)入文件時(shí)现诀,如果文件已存在,會(huì)直接覆蓋(相當(dāng)于刪掉后新寫(xiě)入一個(gè)文件)履肃。如果我們希望追加到文件末尾怎么辦仔沿?可以傳入'a'以追加(append)模式寫(xiě)入。

所有模式的定義及含義可以參考Python的官方文檔尺棋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末封锉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌成福,老刑警劉巖碾局,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異奴艾,居然都是意外死亡擦俐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門握侧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人嘿期,你說(shuō)我怎么就攤上這事品擎。” “怎么了备徐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵萄传,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蜜猾,道長(zhǎng)秀菱,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任蹭睡,我火速辦了婚禮衍菱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肩豁。我一直安慰自己脊串,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布清钥。 她就那樣靜靜地躺著琼锋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祟昭。 梳的紋絲不亂的頭發(fā)上缕坎,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音篡悟,去河邊找鬼谜叹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恰力,可吹牛的內(nèi)容都是我干的叉谜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼踩萎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼停局!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤董栽,失蹤者是張志新(化名)和其女友劉穎码倦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锭碳,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袁稽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了擒抛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片推汽。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖歧沪,靈堂內(nèi)的尸體忽然破棺而出歹撒,到底是詐尸還是另有隱情,我是刑警寧澤诊胞,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布暖夭,位于F島的核電站,受9級(jí)特大地震影響撵孤,放射性物質(zhì)發(fā)生泄漏迈着。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一邪码、第九天 我趴在偏房一處隱蔽的房頂上張望裕菠。 院中可真熱鬧,春花似錦闭专、人聲如沸糕韧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萤彩。三九已至,卻和暖如春斧拍,著一層夾襖步出監(jiān)牢的瞬間雀扶,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工肆汹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留愚墓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓昂勉,卻偏偏與公主長(zhǎng)得像浪册,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岗照,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 文件讀寫(xiě)模式 使用open()函數(shù) 以任何方式使用文件之前村象,都必須打開(kāi)文件笆环;打開(kāi)文件使用open()函數(shù),其返回一...
    ACphart閱讀 7,844評(píng)論 0 1
  • 一厚者、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,744評(píng)論 0 10
  • 袖口處的紐扣 柵欄腳下三三兩兩的丁香 你為我種下那一片草原 江河之上孤舟里的蕭瑟 飲酒誦詩(shī)仰天大笑奔赴夕陽(yáng)的殘光 ...
    涼意眉閱讀 1,235評(píng)論 0 3
  • 方位左西右東躁劣,上南下北。因此整體寫(xiě)字東西方位開(kāi)始库菲,每個(gè)字從左到右寫(xiě)法合乎道账忘。 唱歌,溝通熙宇,職位鳖擒,睡覺(jué),開(kāi)車 人與錢...
    酷代閱讀 850評(píng)論 0 0
  • 學(xué)校給我們發(fā)了韻律操服裝烫止, 今天中午也是韻律操最后一次練習(xí)败去,明天就要正式演出了 希望同學(xué)們繼續(xù)努力, 加油
    青島衛(wèi)校15護(hù)3閱讀 511評(píng)論 0 0