Rozdział 15 · Python i akta

Kursor pliku: tell() i seek()

Otwarty plik ma swoją aktualną pozycję — porusza się do przodu, ale nie wraca do siebie.

Kursor pliku

Otwarty plik zawiera aktualne pozycja odczytu/zapisu jest kursorem. On przesuwa się do przodu podczas odczytu lub zapisu:

kursor.py
with open("alfavit.txt", "w", encoding="utf-8") as f:
    f.write("ABCDE")

with open("alfavit.txt", "r", encoding="utf-8") as f:
    print(f.read(2))   #AB – Kursor przesunął się 2
    print(f.read(2))   #CD – kursor przesunął się o kolejne 2
    print(f.read())    #E – do końca pliku
    print(repr(f.read()))   # '' — kursor już na końcu
0
1
2
3
4
5
A
B
C
D
E
czytaćlewo
kursor przed pierwszym read(2): pozycję 0.
0
1
2
3
4
5
A
B
C
D
E
czytaćlewo
Po read(2): kursor na pozycji 2, odczytano «AB».
0
1
2
3
4
5
A
B
C
D
E
czytaćlewo
Po drugiej read(2): kursor na pozycji 4, odczytano «ABCD».
0
1
2
3
4
5
A
B
C
D
E
czytaćlewo
Po read(): kursorze na końcu pliku (EOF), pozycja 5.
Debug Lab 3: Kursor jest już na końcu pliku
posle_eof.py
with open("alfavit.txt", "r", encoding="utf-8") as f:
    print(f.read())
    print(f.read())   # oczekujemy zobaczyć to samo jeszcze raz?
ABCDE
(пустая строка)
Co widać na ekranie

Drugi f.read() zwrócił pusty łańcuch znaków, a nie „ABCDE” ponownie. Kursor sam nie wraca na początek — po pierwszym read() pozostał na końcu pliku (EOF), i tam już nic do czytania.

Poprawiony kod
vozvrat_v_nachalo.py
with open("alfavit.txt", "r", encoding="utf-8") as f:
    print(f.read())
    f.seek(0)          # ręcznie przywróć kursor do początku
    print(f.read())    # teraz znowu ABCDE

tell() i seek()

tell_seek.py
with open("alfavit.txt", "r", encoding="utf-8") as f:
    f.read(2)
    print(f.tell())   #2 to aktualna pozycja kursora
    f.seek(0)         # Powrót na górę
    print(f.read())   # ABCDE – ponowne czytanie
seek() w trybie tekstowym nie jest „numerem znaku”
Dla prostych przykładów z ASCII-text, przesunięcie zwracające tell(), intuicyjnie odpowiada liczbie przeczytanych znaków. Ale w ogólnym przypadku dla tekstu w UTF-8 to nieprawda: jeden znak (szczególnie cyrylica lub emoji) może zajmować kilka bajtów (rozdział 15.16), a dowolne przesunięcia nie odpowiadają bezpośrednio indeksom znaków. Dla dowolnych przesunięć bajtowych jaśniej i bezpieczniej jest pracować w trybie binarnym (rozdział 15.17). Bezpieczne użycie seek() w trybie tekstowym — seek(0)zacząć od nowa.
Praktyka: Kursor plików, tell() i seek()
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →