12.10 Python seek()和tell()函式詳解
技術標籤:python基礎超詳細Python檔案操作(I/O)
在講解 seek() 函式和 tell() 函式之前,首先來了解一下什麼是檔案指標。
我們知道,使用 open() 函式開啟檔案並讀取檔案中的內容時,總是會從檔案的第一個字元(位元組)開始讀起。那麼,有沒有辦法可以自定指定讀取的起始位置呢?答案是肯定,這就需要移動檔案指標的位置。
檔案指標用於標明檔案讀寫的起始位置。假如把檔案看成一個水流,檔案中每個資料(以 b 模式開啟,每個資料就是一個位元組;以普通模式開啟,每個資料就是一個字元)就相當於一個水滴,而檔案指標就標明瞭檔案將要從檔案的哪個位置開始讀起。圖 1 簡單示意了檔案指標的概念。
圖 1 檔案指標概念示意圖
可以看到,通過移動檔案指標的位置,再借助 read() 和 write() 函式,就可以輕鬆實現,讀取檔案中指定位置的資料(或者向檔案中的指定位置寫入資料)。
注意,當向檔案中寫入資料時,如果不是檔案的尾部,寫入位置的原有資料不會自行向後移動,新寫入的資料會將檔案中處於該位置的資料直接覆蓋掉。
實現對檔案指標的移動,檔案物件提供了 tell() 函式和 seek() 函式。tell() 函式用於判斷檔案指標當前所處的位置,而 seek() 函式用於移動檔案指標到檔案的指定位置。
tell() 函式
tell() 函式的用法很簡單,其基本語法格式如下:
file.tell()
其中,file 表示檔案物件。
例如,在同一目錄下,編寫如下程式對 a.txt 檔案做讀取操作,a.txt 檔案中內容為:
http://c.biancheng.net
讀取 a.txt 的程式碼如下:
f = open("a.txt",'r')
print(f.tell())
print(f.read(3))
print(f.tell())
執行結果為:
0
htt
3
可以看到,當使用 open() 函式開啟檔案時,檔案指標的起始位置為 0,表示位於檔案的開頭處,當使用 read() 函式從檔案中讀取 3 個字元之後,檔案指標同時向後移動了 3 個字元的位置。這就表明,當程式使用檔案物件讀寫資料時,檔案指標會自動向後移動:讀寫了多少個數據,檔案指標就自動向後移動多少個位置。
seek()函式
seek() 函式用於將檔案指標移動至指定位置,該函式的語法格式如下:
file.seek(offset[, whence])
其中,各個引數的含義如下:
- file:表示檔案物件;
- whence:作為可選引數,用於指定檔案指標要放置的位置,該引數的引數值有 3 個選擇:0 代表檔案頭(預設值)、1 代表當前位置、2 代表檔案尾。
- offset:表示相對於 whence 位置檔案指標的偏移量,正數表示向後偏移,負數表示向前偏移。例如,當
whence == 0 &&offset == 3
(即 seek(3,0) ),表示檔案指標移動至距離檔案開頭處 3 個字元的位置;當whence == 1 &&offset == 5
(即 seek(5,1) ),表示檔案指標向後移動,移動至距離當前位置 5 個字元處。
注意,當 offset 值非 0 時,Python 要求檔案必須要以二進位制格式開啟,否則會丟擲 io.UnsupportedOperation 錯誤。
下面程式示範了檔案指標操作:
f = open('a.txt', 'rb')
# 判斷檔案指標的位置
print(f.tell())
# 讀取一個位元組,檔案指標自動後移1個數據
print(f.read(1))
print(f.tell())
# 將檔案指標從檔案開頭,向後移動到 5 個字元的位置
f.seek(5)
print(f.tell())
print(f.read(1))
# 將檔案指標從當前位置,向後移動到 5 個字元的位置
f.seek(5, 1)
print(f.tell())
print(f.read(1))
# 將檔案指標從檔案結尾,向前移動到距離 2 個字元的位置
f.seek(-1, 2)
print(f.tell())
print(f.read(1))
執行結果為:
0
b’h’
1
5
b’/’
11
b’a’
21
b’t’
注意:由於程式中使用 seek() 時,使用了非 0 的偏移量,因此檔案的開啟方式中必須包含 b,否則就會報 io.UnsupportedOperation 錯誤,有興趣的讀者可自定嘗試。
上面程式示範了使用 seek() 方法來移動檔案指標,包括從檔案開頭、指標當前位置、檔案結尾處開始計算。執行上面程式,結合程式輸出結果可以體會檔案指標移動的效果。