IO編程-文件讀寫

Input/Output(輸入/輸出)

由于程序和運行時數(shù)據(jù)是在內(nèi)存中駐留法褥,由CPU這個超快的計算核心來執(zhí)行茫叭,涉及到數(shù)據(jù)交換的地方,通常是磁盤半等、網(wǎng)絡等揍愁,就需要IO接口。

比如你打開瀏覽器杀饵,訪問新浪首頁莽囤,瀏覽器這個程序就需要通過網(wǎng)絡IO獲取新浪的網(wǎng)頁。

  • 瀏覽器首先會發(fā)送數(shù)據(jù)給新浪服務器切距,告訴它我想要首頁的HTML朽缎,這個動作是往外發(fā)數(shù)據(jù),叫Output;
  • 隨后新浪服務器把網(wǎng)頁發(fā)過來谜悟,這個動作是從外面接收數(shù)據(jù)话肖,叫Input。
  • 所以葡幸,通常最筒,程序完成IO操作會有Input和Output兩個數(shù)據(jù)流。

當然也有只用一個的情況:

  • 從磁盤讀取文件到內(nèi)存礼患,就只有Input操作是钥,
  • 把數(shù)據(jù)寫到磁盤文件里,就只是一個Output操作缅叠。
Stream

Stream(流)是一個很重要的概念悄泥,可以把流想象成一個水管,
數(shù)據(jù)就是水管里的水肤粱,但是只能單向流動弹囚。

Input Stream就是數(shù)據(jù)從外面(磁盤、網(wǎng)絡)流進內(nèi)存;
Output Stream就是數(shù)據(jù)從內(nèi)存流到外面去领曼。

對于瀏覽網(wǎng)頁來說鸥鹉,瀏覽器和新浪服務器之間至少需要建立兩根水管蛮穿,才可以既能發(fā)數(shù)據(jù),又能收數(shù)據(jù)毁渗。

同步IO和異步IO

由于CPU和內(nèi)存的速度遠遠高于外設的速度践磅,所以,在IO編程中灸异,就存在速度嚴重不匹配的問題府适。
舉個例子來說,比如要把100M的數(shù)據(jù)寫入磁盤肺樟,CPU輸出100M的數(shù)據(jù)只需要0.01秒檐春,可是磁盤要接收這100M數(shù)據(jù)可能需要10秒,怎么辦呢么伯?

同步IO:CPU等著疟暖,也就是程序暫停執(zhí)行后續(xù)代碼,等100M的數(shù)據(jù)在10秒后寫入磁盤田柔,再接著往下執(zhí)行
異步IO:CPU不等待俐巴,只是告訴磁盤,“您老慢慢寫凯楔,不著急窜骄,我接著干別的事去了”,于是摆屯,后續(xù)代碼可以立刻接著執(zhí)行

一邻遏、讀文件:open-read-close(必須):with-open-read

import logging
logging.basicConfig(level=logging.INFO)
'''1
讀文件:使用Python內(nèi)置的open()函數(shù),傳入文件名和標示符虐骑;
標示符'r'表示讀准验;
'''
f=open(r'data_center_test\share\h.txt','r')
'''2
文件打開成功,調(diào)用read()方法可以一次讀取文件的全部內(nèi)容;
Python把內(nèi)容讀到內(nèi)存廷没,用一個str對象表示;
'''
logging.info(f.read())
'''3
最后調(diào)用close()方法關(guān)閉文件糊饱。
文件使用完畢后必須關(guān)閉;
因為文件對象會占用操作系統(tǒng)的資源,并且操作系統(tǒng)同一時間能打開的文件數(shù)量也是有限的
'''
f.close()

'''4
由于文件讀寫時都有可能產(chǎn)生IOError颠黎,一旦出錯另锋,后面的f.close()就不會調(diào)用。
所以狭归,為了保證無論是否出錯都能正確地關(guān)閉文件夭坪,我們可以使用try ... finally來實現(xiàn)
'''
try:
    f = open(r'data_center_test\share\h.txt', 'r')
    print(f.read())
finally:
    if f:
        f.close()
問題:關(guān)于文件路徑中轉(zhuǎn)義字符問題
  • 在路徑前面加r,即保持字符原始值的意思过椎。
    open(r'data_center_test\share\h.txt', 'r')
  • 替換為雙反斜杠
    open('data_center_test\\share\\h.txt', 'r')
  • 替換為正斜杠
    open('data_center_test/share/h.txt', 'r')
1室梅、with

Python引入了with語句來自動幫我們調(diào)用close()方法:

with open(r'data_center_test\share\h.txt', 'r') as f:
    print(f.read())

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

2亡鼠、read()
  • read():會一次性讀取文件的全部內(nèi)容赏殃;
  • read(size):如果文件有10G,內(nèi)存就爆了间涵,所以仁热,要保險起見,可以反復調(diào)用read(size)方法勾哩,每次最多讀取size個字節(jié)的內(nèi)容
  • readline():可以每次讀取一行內(nèi)容股耽;
  • readlines():一次讀取所有內(nèi)容并按行返回list;
with open(r'data_center_test\share\h.txt', 'r') as f:
    for line in f.readlines():
        print(line.strip()) 
問題:python f.read()讀取文件為空
  • 可能原因1:
    多次調(diào)用f.read()钳幅,第一次調(diào)用f.read()可以讀取到內(nèi)容,這時游標會移動到文章末尾炎滞,再次調(diào)用f.read()是獲取不到內(nèi)容的敢艰,可以使用f.seek(0)將游標移動到文章開頭再次調(diào)用f.read()即可獲取內(nèi)容。

  • 可能原因2:
    在使用f.write()向文件內(nèi)寫入內(nèi)容后立刻使用f.read()讀取文件內(nèi)容册赛,這時游標也是在文件末尾的钠导,也獲取不到文本,解決方法同上森瘪。

二牡属、二進制文件

前面講的默認都是讀取文本文件,并且是UTF-8編碼的文本文件扼睬。要讀取二進制文件逮栅,比如圖片、視頻等等窗宇,用'rb'模式打開文件即可

with open(r'data_center_test\share\1.png', 'rb') as f:
    print(f.read()) 
b'\xff\xd8\xff\xe0\x00\........... # 十六進制表示的字節(jié)

三措伐、字符編碼

1、encoding參數(shù):要讀取非UTF-8編碼的文本文件军俊,需要給open()函數(shù)傳入encoding參數(shù)
2侥加、errors參數(shù):表示如果遇到編碼錯誤或不規(guī)范的情況后直接忽略處理
(有些會報UnicodeDecodeError錯誤,因為在文本文件中可能夾雜了一些非法編碼的字符)

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

四粪躬、寫文件:open-write-close(必須):with-open-write

但是務必要調(diào)用f.close()來關(guān)閉文件担败。
當我們寫文件時,操作系統(tǒng)往往不會立刻把數(shù)據(jù)寫入磁盤镰官,而是放到內(nèi)存緩存起來提前,空閑的時候再慢慢寫入
只有調(diào)用close()方法時,操作系統(tǒng)才保證把沒有寫入的數(shù)據(jù)全部寫入磁盤朋魔。
忘記調(diào)用close()的后果是數(shù)據(jù)可能只寫了一部分到磁盤岖研,剩下的丟失了。
所以,還是用with語句來得保險:

with open(r"data_center_test\share\h.txt", "w") as f:
    f.write("你好呀")

以'w'模式寫入文件時孙援,如果文件已存在害淤,會直接覆蓋(相當于刪掉后新寫入一個文件)。
可以傳入'a'以追加(append)模式寫入

五拓售、open模式

模式 描述
r 以只讀方式打開文件窥摄。文件的指針將會放在文件的開頭。這是默認模式础淤。
rb 以二進制格式打開一個文件用于只讀崭放。文件指針將會放在文件的開頭。這是默認模式鸽凶。一般用于非文本文件如圖片等币砂。
w 打開一個文件只用于寫入。如果該文件已存在則打開文件玻侥,并從開頭開始編輯决摧,即原有內(nèi)容會被刪除。如果該文件不存在凑兰,創(chuàng)建新文件掌桩。
wb 以二進制格式打開一個文件只用于寫入。如果該文件已存在則打開文件姑食,并從開頭開始編輯波岛,即原有內(nèi)容會被刪除。如果該文件不存在音半,創(chuàng)建新文件则拷。一般用于非文本文件如圖片等。
a 打開一個文件用于追加曹鸠。如果該文件已存在隔躲,文件指針將會放在文件的結(jié)尾。也就是說物延,新的內(nèi)容將會被寫入到已有內(nèi)容之后宣旱。如果該文件不存在,創(chuàng)建新文件進行寫入叛薯。
ab 以二進制格式打開一個文件用于追加浑吟。如果該文件已存在,文件指針將會放在文件的結(jié)尾耗溜。也就是說组力,新的內(nèi)容將會被寫入到已有內(nèi)容之后。如果該文件不存在抖拴,創(chuàng)建新文件進行寫入燎字。

小結(jié):
在Python中腥椒,文件讀寫是通過open()函數(shù)打開的文件對象完成的。使用with語句操作文件IO是個好習慣

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末候衍,一起剝皮案震驚了整個濱河市笼蛛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛉鹿,老刑警劉巖滨砍,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妖异,居然都是意外死亡惋戏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門他膳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來响逢,“玉大人,你說我怎么就攤上這事棕孙×渚洌” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵散罕,是天一觀的道長。 經(jīng)常有香客問我傀蓉,道長欧漱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任葬燎,我火速辦了婚禮误甚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谱净。我一直安慰自己窑邦,他們只是感情好,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布壕探。 她就那樣靜靜地躺著冈钦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪李请。 梳的紋絲不亂的頭發(fā)上瞧筛,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音导盅,去河邊找鬼较幌。 笑死,一個胖子當著我的面吹牛白翻,可吹牛的內(nèi)容都是我干的乍炉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岛琼!你這毒婦竟也來了底循?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤衷恭,失蹤者是張志新(化名)和其女友劉穎此叠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體随珠,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡灭袁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窗看。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茸歧。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖显沈,靈堂內(nèi)的尸體忽然破棺而出软瞎,到底是詐尸還是另有隱情,我是刑警寧澤拉讯,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布涤浇,位于F島的核電站,受9級特大地震影響魔慷,放射性物質(zhì)發(fā)生泄漏只锭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一院尔、第九天 我趴在偏房一處隱蔽的房頂上張望蜻展。 院中可真熱鬧,春花似錦邀摆、人聲如沸纵顾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽施逾。三九已至,卻和暖如春例获,著一層夾襖步出監(jiān)牢的瞬間音念,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工躏敢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闷愤,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓件余,卻偏偏與公主長得像讥脐,于是被迫代替她去往敵國和親遭居。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

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