python--檔案處理,
在python中如果想對硬碟中的一個檔案進行操作大概可以分為三步,它的流程如下:
1、使用open函數開啟一個檔案控制代碼,並且賦值給一個變數。
2、通過相應的檔案控制代碼對指定的檔案進行操作
3、操作完成後關閉檔案,檔案關閉後,會將檔案內容寫入到磁碟中。
open函數的使用方法如下。
open(‘檔案路徑’,mode=‘開啟檔案的模式‘,encoding='檔案編碼方式')
1、檔案路徑:這個檔案路徑可以是絕對路徑,也可以是相對路徑,在python中相對路徑只需要寫檔案名稱就可以了,如果python程式和需要大開的檔案如果在一個目錄的話,直接使用相對路徑就可以了。
注意!如果要使用open函數,檔案路徑是必要參數,不可以不傳!
2、開啟檔案的模式:open函數裡面有一個非必要形參,就是mode,它用來定義檔案的開啟模式,如果不指定檔案開啟模式,預設情況下會使用r(唯讀)模式開啟檔案。
python中所提供的熱門檔案開啟檔案如下:
'r' 以唯讀模式開啟檔案,使用r(唯讀模式)開啟檔案,檔案只能讀,不能做寫操作。(檔案不存在,則拋出異常)
'w'以唯寫模式開啟檔案,使用w(唯寫模式)開啟檔案,檔案只能寫,不能讀取,不過有一點需要特別注意!!!!!一個原本就有內容的檔案,一旦使用w開啟,那麼這個檔案的內容會被清空!!(至於原因,本文後面會補充。)(如果不想檔案原來的內容被清空!!那麼千萬不要使用w模式!!!!!!!)(檔案不存在時,會建立一個檔案,如果檔案存在,則會先清空檔案內容)
'a' 追加模式,也是一種唯寫模式,用於在問價的尾部追加內容,所寫入的內容都會追加到檔案的末尾處
'b' 二進位模式,使用二進位的方式來開啟檔案,注意!這個‘b’(二進位模式)是要與(r,w,a)三種模式組合使用的。(跨平台跨作業系統建議使用此模式)
'r+' 可讀可寫(在這種模式下,雖然可讀可寫,但是寫的時候一定要注意,seek指標還在檔案的頭部,如果沒有調整seek指標的位置直接開始寫入,會直接開始覆蓋前面寫的內容(從檔案頭部開始),所以說,在使用r+模式的時候,一定要注意seek指標的位置,在檔案的什麼地方!!否則會覆蓋原有內容。)
'w+' 可寫可讀 (這個模式一般情況下不要用,也會直接清空檔案)
'a+' 末尾追加,可寫可讀
一.對檔案對象進行操作的常用方法
讀檔案:
readable()用於判斷檔案是否可讀,如果可讀返回True,否則返回False。
readline() 一次讀取檔案的一行,返回字串類型。
read()一次讀取檔案所有的內容,返回一整個字串。
readlines()讀取檔案的所有內容,並把檔案的每一行內容添加到一個列表裡面,檔案的每一行內容都將作為列表中的一個元素。
寫檔案:
writable():判斷檔案是否可寫,如果可寫,返回True,否則返回False。
write():在檔案中寫入內容,只有當檔案處於可寫的模式,才可以使用此方法,具體在檔案的什麼位置寫,則取決於檔案的開啟模式(是r+還是a+或者是w+)還有就是取決於當前的seek指標所指向檔案的什麼位置。(在補充一點,使用write方法向檔案內部寫內容,是沒有分行符號的,需要手動添加個分行符號,不然所有的內容都會粘到一起。)
例:f1.write('hello!\n') #\n就是分行符號。
writelines():和wirte類似,都是向檔案內部寫入內容,和write不同的是,writelines是使用列表的形式來對檔案內部寫入內容,使用writelines方法,python會將列表迴圈,列表中的每個元素都會寫入到檔案中。
注意!使用writelines對檔案內部寫內容時,也是不帶分行符號的,如果給每個元素的尾部都加個分行符號,那麼列表中的每一個元素都是檔案中的一行。
注意!!在檔案中寫入的內容只能是字串,不可以是其他類型!!否則會拋出異常,就算要寫入數字,那麼這個數字也一定要轉換成字串類型!!!
其他動作:
close()關閉檔案,當檔案使用讀完或者寫完後一定要使用close關閉檔案!(使用with文法除外,因為使用with關鍵字開啟檔案,對檔案的操作結束後,會自動關閉檔案)。
讀完檔案後不關閉,程式會一直佔用系統資源。
寫完檔案後不關閉,會導致記憶體中的內容不會及時的同步到硬碟中,若想把內容徹底寫到硬碟,要不然就使用close關掉檔案,要不然,就使用flush方法強制把記憶體中的資料刷到硬碟上。
flush()將記憶體中沒有寫到硬碟上的資料,強刷到硬碟中。
encoding:顯示檔案開啟的編碼(在python2中沒有這個方法,在python3中可以使用。)
tell():可以擷取當前seek指標的位置。
seek(指標位置 ,模式)以位元組為單位,移動seek指標,在檔案中的位置。
在pyrhon中對seek指標的操作有三種模式,下面對這三種模式進行一個詳細的介紹:
file.seek(n,0)#n代表了指標的位置,後面的數字0代表的是模式的序號。
file.seek(n,0):(模式0)模式0代表了,絕對位置,n為幾,就會把指標移動到從檔案開頭開始算數的第幾個位元組。(在使用seek時,如果不指定模式,那麼預設的模式就是0。)
比如說file.seek(3,0) 將指標移動到從檔案的開頭(第0個位元組)開始數,三個位元組的位置。
#沒使用指標之前
f1 = open('seasons.lrc',mode='r')
print f1.readline()
#下面是使用0模式,將指標移動到檔案的第3個位元組,將指標移動到第3個位元組以後,在去讀檔案,就會從指標的後面開始讀檔案。
f1 = open('seasons.txt',mode='r')
print f1.tell() #顯示一下seek指標當前的位置
>>>0 #(位置是0,代表指標在檔案的開頭)
f1.seek(3,0) #(將指標移動到第三個位元組處,使用0模式,絕對位置)
print f1.tell() #再次查看指標位置,可以驗證指標的位置確實被移動到了第三個位元組處。
>>>3
print f1.readline() #從當前指標的位置後面讀取一行。
這時可能有人要問了,讀檔案是從指標的後面開始讀的沒錯,但是明明把指標移動到了三個位元組之後啊,為什麼才跳過了一個字元?
這就需要瞭解什麼是字元和位元組了,一定要清楚這個概念!!在utf-8的字元編碼中,一個漢字會佔用三個位元組,原來第一行的內容是“浜崎あゆみ - Seasons”,因為一個漢字佔了三個位元組,所以指標被向後移動了三個位元組,正好是一個漢字的位置,指標被移動到了“浜”後面,讀檔案的話,就從這個字後面開始讀, 所以顯示的就是“崎あゆみ - Seasons”。(一個日文字元在utf-8字元編碼中也佔三個位元組。)
後面在舉個例子,這個例子可以明白“絕對位置”的意思。
f1 = open('seasons.lrc',mode='r')
print f1.tell() #開啟檔案後,指標預設的位置是0。
>>>0
f1.seek(3,0) #將指移動到檔案中3個位元組的位置。
print f1.tell()
>>>3
f1.seek(3,0)
print f1.tell()
>>>3
file.seek(n,1): (模式1)模式1,相對位置,n代表了指標在當前位置向後移動幾個位元組。
如果覺得我說的不太容易懂的話,估計看下後面的例子,就懂了。
f1 = open('seasons.lrc',mode='r')
print f1.tell() #開啟檔案後,指標預設的位置是0。
>>>0
f1.seek(3,1) #將指標向後移動3個位元組的位置。
print f1.tell()
>>>3 #指標移動到了第3個位元組的位置。
f1.seek(3,1) #這裡是重點了,將指標在向後移動3個位元組(在這個地方就可以比較出模式1和模式0的區別了。)
print f1.tell()
>>>6 #指標的位置在第6個位元組上,這也就說明了,1模式每次移動,並不是從檔案的開頭開始算起,而是根據指標上次所在的位置開始向後移動。(這也就是“相對位置”的意思。)
如果還看不懂,那就看下面的補充。
最後在補充一下:
f1.seek(3,0) 是指,將指標移動到檔案第3個位元組的位置。(絕對位置)
f1.seek(3,1) 是指,將指標從當前位置向後移動3個位元組的位置。(相對位置)
file.seek(-n,2): 以絕對位置,從檔案最末尾開始,向檔案的開頭移動。(在使用2模式時,需要注意,指標移動的位置只能是負數,因為是從最末尾開始向前移動!)
下面是例子:
#開啟一個檔案,使用read方法從頭讀到檔案的尾部,當檔案被讀完,指標自然就回移到檔案的末尾。
f1 = open('seasons.txt',mode='r')
print f1.tell()
>>>0
f1.read()
print f1.tell()
>>>756
現在通過上面的方法已經知道,檔案的最末尾是檔案的第幾個位元組。
下面來測試下seek方法的2模式的功能是否如之前所說,從檔案最末尾開始,向檔案的開頭移動。
f1 = open('seasons.txt',mode='r')
print f1.tell()
>>>0
f1.seek(-1,2) #使用seek的2模式,將指標從檔案的最末尾向前移動1個位元組
print f1.tell()
>>>755
#檔案的最末尾是756,向前移動了一個位元組就是755,得到了我們想要得到的效果。
其實seek方法的2模式還是比較有用的,下面就細說下seek方法的2模式。
在擷取檔案的倒數第1行到第N行,就可以使用seek方法的2模式。
這時可能會有人問,取出檔案的最後一行,豈不是很簡單的操作,只要使用readlines方法把檔案都讀出來,然後取最後一個元素,就可以取到最後一行了,這種方法豈不是更簡單?
像這樣。
f1 = open('seasons.txt',mode='r')
print f1.readlines()[-1]
檔案的最後一行確實被取出來了,但是,有沒有想過,這種使用readlines讀取檔案的本質,是把檔案的每一行全部讀到記憶體中,如果這個檔案特別大,比如說10個G,100G,大到當前的記憶體放不下,如果是這種情況,這種方法就不適用了。
下面這種方法,對於大檔案就特別適用了。
f1 = open('seasons.txt',mode='r')
for i in f1: #直接for迴圈檔案控制代碼,並不會一次性把檔案都讀到記憶體,而是讀一行從檔案中取一行。
line_bytes = -36
while True:
f1.seek(line_bytes,2)
data = f1.readlines()
if len(data) > 1:
print data[-1]
break
else:
line_bytes * 2