Python - Datoteke I/O


Datoteke (Files)

Datoteke su imenovane lokacije na disku za pohranu povezanih informacija. Koriste se za trajno spremanje podataka u trajnu memoriju (npr. tvrdi disk - hard disk). Budući da je memorija s slučajnim pristupom (RAM) hlapljiva (koja svoje podatke gubi kad je računar isključen), datoteke koristimo za buduću upotrebu podataka trajnim skladištenjem.

Kada želimo čitati iz datoteke ili pisati u nju, prvo je moramo otvoriti. Kada završimo, potrebno je zatvoriti datoteke kako bi se oslobodili resursi povezani s datotekom. Zbog toga se u Pythonu operacija datoteke odvija sljedećim redoslijedom:

  1. Otvorite datoteku
  2. Čitanje ili pisanje (izvođenje operacije)
  3. Zatvorite datoteku


Otvaranje datoteka u Pythonu

Python ima ugrađenu funkciju open() za otvaranje datoteke. Ova funkcija vraća objekt datoteke, koji se naziva i ručicom (handle), jer se koristi za čitanje ili izmjenu datoteke u skladu s tim.

>>> f = open("test.txt")    # otvori datoteku u trenutnom direktorijumu
>>> f = open("C:/Python38/README.txt")  # specifikacija pune putanje

Način možemo odrediti tokom otvaranja datoteke. U načinu određujemo želimo li čitati r, pisati w ili dodavati a datoteci. Takođe možemo odrediti želimo li datoteku otvoriti u tekstualnom ili binarnom načinu. Zadana postavka je čitanje u tekstualnom načinu. U ovom načinu dobijamo stringove prilikom čitanja iz datoteke.

S druge strane, binarni način vraća bajtove i to je način koji će se koristiti pri radu s netekstualnim datotekama poput slika ili izvršnih datoteka.

Način rada Opis
r Otvara datoteku za čitanje. (zadano)
w Otvara datoteku za pisanje. Stvara novu datoteku ako ne postoji ili je skraćuje ako postoji.
x Otvara datoteku za ekskluzivno stvaranje. Ako datoteka već postoji, operacija ne uspije.
a Otvara datoteku za dodavanje na kraj datoteke bez da je skraćuje. Stvara novu datoteku ako ona ne postoji.
t Otvara se u tekstualnom načinu. (zadano)
b Otvara se u binarnom načinu.
+ Otvara datoteku za ažuriranje (čitanje i pisanje)
f = open("test.txt")      # ekvivalentno 'r' ili 'rt'
f = open("test.txt",'w')  # pisanje u tekstualnom modu
f = open("img.bmp",'r+b') # čitatanje i pisanje u binarnom modu

Za razliku od ostalih jezika, znak a ne podrazumijeva broj 97 dok nije kodiran pomoću ASCII (ili drugih ekvivalentnih kodiranja). Štoviše, zadano kodiranje zavisi o platformi. U Windowsima je cp1252, ali utf-8 u Linuxu.

Dakle, ne smijemo se takođe oslanjati na zadano kodiranje, jer će se inače naš kod drugačije ponašati na različitim platformama. Zbog toga se kod rada s datotekama u tekstualnom načinu preporučuje preporuka da se navede vrsta kodiranja.

f = open("test.txt", mode='r', encoding='utf-8')


Zatvaranje datoteka u Pythonu

Kada završimo s obavljanjem operacija na datoteci, moramo pravilno zatvoriti datoteku. Zatvaranjem datoteke oslobodiće se resursi povezani s datotekom. To se radi pomoću metode close() koja je dostupna u Pythonu. Python ima sakupljač smeća za čišćenje neferisanih objekata, ali ne smijemo se oslanjati na njega da bi zatvorio datoteku.

f = open("test.txt", encoding = 'utf-8')
# izvoditi operacije datoteka
f.close()

Ova metoda nije u potpunosti sigurna. Ako se izuzetak dogodi kada izvodimo neku operaciju s datotekom, kod izlazi bez zatvaranja datoteke. Sigurniji način je korištenje try...finally bloka.

try:
   f = open("test.txt", encoding = 'utf-8')
   # izvoditi operacije datoteka
finally:
   f.close()

Na ovaj način garantujemo da je datoteka pravilno zatvorena, čak i ako se pokrene izuzetak koji zaustavlja protok programa. Najbolji način za zatvaranje datoteke je pomoću naredbe with. Ovo osigurava zatvaranje datoteke kada se izađe iz bloka unutar naredbe with. Ne trebamo izričito pozivati metodu close(). To se radi interno.

with open("test.txt", encoding = 'utf-8') as f:
   # izvoditi operacije datoteka


Pisanje u datoteke u Python-u

Da bismo pisali u datoteku u Python-u, moramo je otvoriti u načinu pisanja w, dodati a ili ekskluzivnom načinu kreiranja x. Moramo biti oprezni s režimom w, jer će se on prepisati u datoteku ako već postoji. Zbog toga se brišu svi prethodni podaci.

Zapisivanje stringa ili sekvence bajtova (za binarne datoteke) vrši se metodom write(). Ova metoda vraća broj znakova zapisanih u datoteku.

with open("test.txt",'w',encoding = 'utf-8') as f:
   f.write("moja prva datoteka\n")
   f.write("Ova datoteka\n\n")
   f.write("sadrži tri reda\n")

Ovaj program će stvoriti novu datoteku nazvanu test.txt u trenutnom direktoriju ako ona ne postoji. Ako postoji, prepisuje se. Moramo sami uključiti znakove novog reda da bismo razlikovali različite redove.



Čitanje datoteka u Pythonu

Da bismo pročitali datoteku u Pythonu, moramo je otvoriti u režimu čitanja r. U tu svrhu postoje razne metode. Možemo koristiti metodu čitanja (veličina) za čitanje broja podataka veličine. Ako parametar size nije naveden, on čita i vraća se do kraja datoteke. Datoteku text.txt koju smo napisali u gornjem dijelu možemo pročitati na sljedeći način:

>>> f = open("test.txt",'r',encoding = 'utf-8')
>>> f.read(4)    # pročitajte prva 4 podatka
'Ovo '

>>> f.read(4)    # pročitajte sljedeća 4 podatka
'dato'

>>> f.read()     # pročitajte u ostatku do kraja datoteke
'moja prva datoteka\nOva datoteka\nsadrži tri reda\n'

>>> f.read()  # daljnje čitanje vraća prazan string
''

Vidimo da metoda read() vraća novu liniju kao '\n'. Jednom kada se dođe do kraja datoteke, dobićemo prazan string za daljnje čitanje. Možemo promijeniti trenutni položaj datoteke pomoću metode search(). Slično tome, metoda tell() vraća našu trenutnu poziciju (u broju bajtova).

>>> f.tell()    # dobijanje trenutne pozicije datoteke
56

>>> f.seek(0)   # dovedođenje pložaja datoteke na početni položaj
0

>>> print(f.read())  # pročitajte cijelu datoteku
Moja prva datoteka
Ova datoteka
sadrži tri reda

Datoteku možemo čitati red po red pomoću for petlje. Ovo je i efikasno i brzo.

>>> for line in f:
...     print(line, end = '')
...
Moja prva datoteka
Ova datoteka
sadrži tri reda

U ovom programu linije u samoj datoteci uključuju znak za novi red \n. Dakle, koristimo krajnji parametar funkcije print() kako bismo izbjegli dva nova reda prilikom ispisa. Alternativno, možemo koristiti metodu readline() za čitanje pojedinačnih redova datoteke. Ova metoda čita datoteku do novog reda, uključujući znak novog reda.

>>> f.readline()
'Moja prva datoteka\n'

>>> f.readline()
'Ova datoteka\n'

>>> f.readline()
'sadrži tri reda\n'

>>> f.readline()
''

Na kraju, metoda readlines() vraća listu preostalih redova cijele datoteke. Sve ove metode čitanja vraćaju prazne vrijednosti kada se dostigne kraj datoteke (EOF).

>>> f.readlines()
['Moja prva datoteka\n', 'Ova datoteka\n', 'sadrži tri reda\n']


Metode Python datoteke

Postoje razne metode dostupne s objektom datoteke. Neki od njih su korišteni u gornjim primjerima. Ovdje je kompletna lista metoda u tekstualnom načinu s kratkim opisom:

Metoda Opis
close() Zatvara otvorenu datoteku. Nema učinka ako je datoteka već zatvorena.
detach() Odvaja temeljni binarni međuspremnik od TextIOBase i vraća ga.
fileno() Vraća cijeli broj (deskriptor datoteke) datoteke.
flush() Osvježava međuspremnik za pisanje toka datoteka.
isatty() Vraća True ako je tok datoteka interaktivan.
read(n) Čita najviše n znakova iz datoteke. Čita do kraja datoteke ako je negativna ili None.
readable() Vraća True ako se može čitati tok datoteka.
readline(n=-1) Čita i vraća jedan red iz datoteke. Čita u najviše n bajtova ako je navedeno.
readlines(n=-1) Čita i vraća listu linija iz datoteke. Čita najviše n bajtova/znakova ako je navedeno.
seek(offset,from=SEEK_SET) Mijenja položaj datoteke u offset bajtova, u odnosu na from (start, current, end).
seekable() Vraća True ako tok datoteka podržava nasumični pristup.
tell() Vraća trenutnu lokaciju datoteke.
truncate(size=None) Mijenja veličinu toka datoteke na bajtove veličine. Ako veličina nije navedena, veličina se mijenja na trenutnu lokaciju.
writable() Vraća True ako se na tok datoteka može zapisati.
write(s) Zapisuje string s u datoteku i vraća broj napisanih znakova.
writelines(lines) Zapisuje listu linija u datoteku.