本文以Python3以上為學習基礎。
read、readline、readlines都是取檔案内容。
三者有什麼差別?
我們先看三個函數的文法格式:
1、read()
fileObject.read([size])
size:如果指定了參數size,就按照該指定長度從檔案中讀取内容,否則,就讀取全文。被讀出來的内容,全部塞到一個字元串裡面。<通常不使用這個參數>
這樣有好處,就是東西都到記憶體裡面了,随時取用,比較快捷;“成也蕭何敗蕭何”,也是因為這點,如果檔案内容太多了,記憶體會吃不消的。
我們來驗證一下。
1.1 不指定參數的情況
建立檔案zxc.txt,内容如下:
下面讀取檔案:
很明顯,我們出現了以下錯誤:
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x82 in position 75:
incomplete multibyte sequence
主要原因是因為編碼的問題,可能是因為0x82這個位元組在gbk編碼中沒有這個字元,可能原字元是兩個位元組,在gbk裡被解析成了一個位元組,導緻字元不存在。解決方法有兩個,一個是二進制讀取,一個是改編編碼方式:
二進制讀取
這就是我們檔案打開方式有二進制的原因。
下面我們進行驗證。
可以看到,二進制就把檔案内容讀出來了。與原來是中文的句号在gbk裡面沒有。
雖然參數使用的情況通常不用,但是下面我們還是看看指定參數的情況:
1.2 指定參數的情況
檔案内容:
下面指定參數打開檔案:
可以看到,固定讀取四個位元組,得到最開始四個位元組:This。
2、readline()
fileObject.readline(size)
size:如果指定了參數size,就按照該指定的讀取的位元組數從檔案中讀取内容,否則,就每次讀取一行。被讀出來的内容,全部塞到一個字元串裡面。<通常不使用>
readline()方法每次讀取一行,傳回的是一個字元串對象,保持目前行的記憶體。
我們來驗證一下。
首先還是一樣,沒有參數的場合:
2.1 不指定參數的情況
檔案内容如下:
下面我們利用readline讀取檔案内容。
這次為了避免看着麻煩,就把檔案中的中文句号給去除了,是以我們直接用讀模式r打開就好。
可以看到我們把第一行給都出來了。
其實每操作一次 tmp.readline(),就讀取一行,并且将指針向下移動一行。是以,我們如果說利用一種循環,或者說可疊代的來完成對全文的讀取。
下面我們看看:
檔案内容還是一樣:
下面利用循環語句,利用readline函數,循環讀取檔案内容。
結果顯而易見,循環讀取每一行的内容,整個檔案的内容讀取出來了。
這裡說一個題外話:
注意:在python中,’\n’表示換行,這也是UNIX系統中的規範。但是,在奇葩的windows中,用’\r\n’表示換行。python是永遠滴神,python在處理這個的時候,會自動将’\r\n’轉換為’\n’。
很簡單我們試試看:
我目前的運作環境是:Windows10、Anaconda3、Python3.5
我們利用二進制把檔案打開看看:
檔案内容:
我們用readline函數讀取一行,打開模式是二進制方式隻讀。 可以看到,檔案的最後的換行符是:\r\n
還是一樣,參數通常不用,但是我們來試試有參數的場合:
2.2 指定參數的情況
不多說,直接上示例。
檔案内容:
我們用readline函數,指定參數,讀取檔案:
可以看到,傳回結果是:1 This(1和This之間是兩個空格)
3、readlines()
fileObject.readlines()
我們可以看到readlines函數是沒有參數的。
readlines() 方法用于讀取所有行(直到結束符 EOF)并傳回清單。它傳回的是以行為機關的清單,即相當于先執行readline(),得到每一行,然後把這一行的字元串作為清單中的元素塞到一個清單中,最後将此清單傳回。
該清單可以由 Python 的 for… in … 結構進行處理。
如果碰到結束符 EOF 則傳回空字元串。
不多說,我們試試看:
檔案内容:
利用readlines函數讀取問津内容,并且我們列印讀取後的變量類型:
可以看到,最後的記過放在了清單中。
清單中的每個元素就是對應每行的内容,甚至結尾的換行符\n都存在。
既然是清單,那麼就可以利用for循環周遊。
以下就是for循環的結果:
我們總結一下三個讀取函數:
4、總結
函數 | 有無參數 | 傳回值 |
---|---|---|
read | 有、size:指定讀取長度。 | 讀取結果傳回到字元串裡面,并且存在記憶體中。 |
readline | 有、size:指定讀取長度。 | 以行為機關傳回字元串,也就是每次讀一行 |
readlines | 無 | 傳回清單,每個清單元素就是一行内容,包括最後的換行符。 |
5、讀很大的檔案
如果檔案太大,就不能用read()或者readlines()一次性将全部内容讀入記憶體,否則記憶體頂不住的。
但是可以使用while循環和readline()來完成這個任務。一行一行的讀。
除此之外還有一個辦法:fileinput子產品
這個子產品後續講解。
我們直接看用法,一看就懂:
檔案内容如下,我們就當檔案很大,模拟一下。
利用fileinput子產品讀取檔案:
我比較喜歡這個,簡潔明快,還用for。
其實還有一個更常用的:
之是以能夠如此,是因為file是可疊代的資料類型,直接用for來疊代即可。