Datoteke¶
Tekstualne datoteke¶
Primjer koji upisuje neka slova i brojeve u datoteku.
with open("txt1.txt","w") as f: print("1.red: 123", 456, file=f) print("2.red 1230", 4560.123, file=f)
Rezultat je datoteka:
1.red: 123 456 2.red 1230 4560.123
U C-u je običaj štedljivo učitavati ono što je potrebno broj po broj slovo po slovo. U pythonu je običaj učitati odjednom sve a nakon toga analizirati.
with open("txt1.txt","r") as f:
s = f.read()
print(s)
1.red: 123 456
2.red 1230 4560.123
Sadržaj učitan u jedan veliki string. |
with open("txt1.txt","r") as f:
L = f.readlines()
print(L)
['1.red: 123 456\n', '2.red 1230 4560.123\n']
Sadržaj učitan kao lista stringova: jedan red = jedan string. |
with open("txt1.txt","r") as f:
L = f.readlines()
for red in L:
L1 = red.split()
print(L1[:-1], float(L1[-1]))
['1.red:', '123'] 456.0
['2.red', '1230'] 4560.123
Sadržaj učitan kao lista stringova. Zatim svaki red rastavljen u listu stringova. Zadnji element liste pretvaramo u |
Napomena
Datoteke se zatvaraju u trenutku napuštanja with
bloka, tj. nakon izvršenja zadnje naredbe u with
bloku.
Tekstualni format JSON¶
JSON omogućuje lagano prebacivanje iz kombinacije dictionary+list+osnovni tipovi u string i obratno. Time se lako mogu iz datoteke učitati npr. ulazni podaci za program.
>>> import json
>>> čestice = [{'rb':1, 'm':10, 'x':0.0, 'y':0.0, 'fiksna':True}, {'rb':2, 'm':20, 'x':1.0, 'y':1.1, 'fiksna':False}]
>>> print(čestice[0]['rb'])
1
>>> print(čestice[0]['x'])
0.0
>>> print(čestice[0]['y'])
0.0
>>> print(čestice[1]['rb'])
2
>>> print(čestice[1]['x'])
1.0
>>> print(čestice[1]['y'])
1.1
>>> print(repr(json.dumps(čestice)))
'[{"rb": 1, "m": 10, "x": 0.0, "y": 0.0, "fiksna": true}, {"rb": 2, "m": 20, "x": 1.0, "y": 1.1, "fiksna": false}]'
>>> print(json.dumps(čestice,indent=4))
[
{
"rb": 1,
"m": 10,
"x": 0.0,
"y": 0.0,
"fiksna": true
},
{
"rb": 2,
"m": 20,
"x": 1.0,
"y": 1.1,
"fiksna": false
}
]
U gornjem primjeru smo pomoću json.dumps()
prebacili sadržaj varijable u string.
Pomoću json.dump()
sadržaj varijable upisujemo u datoteku.
import json
data = {'datum':'2018-09-01','popis':[(1,2),5,10,15]}
with open("json1.txt","w") as f:
json.dump(data,f)
U datoteci je upisano:
{"datum": "2018-09-01", "popis": [[1, 2], 5, 10, 15]}
Učitavanje iz stringa radimo pomoću json.loads()
a iz datoteke pomoću json.load()
.
import json
with open("json1.txt","r") as f:
data = json.load(f)
print(data)
print(data['popis'])
{'datum': '2018-09-01', 'popis': [[1, 2], 5, 10, 15]}
[[1, 2], 5, 10, 15]
Binarne datoteke¶
Strukture¶
C interno u memoriji drži samo gole podatke koje je stoga lako direktno prepisati iz memorije u datoteku. Python interno u memoriji drži puno više dodatnih informacija pa je potrebno prije upisa u datoteku izvući same podatke u obliku liste byteova. To se radi pomoću funkcije struct.pack()
.
>>> import struct >>> print(struct.pack('10s',b"tekst")) b'tekst\x00\x00\x00\x00\x00' >>> print(struct.pack('20s',b"tekst")) b'tekst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' >>> print(struct.pack('i',10)) b'\n\x00\x00\x00' >>> print(struct.pack('d',0.1)) b'\x9a\x99\x99\x99\x99\x99\xb9?'
Slijedi primjeri koji upisuju i čitaju riječ, int
i double
u datoteku.
import struct
L=[b"tekst",10,0.1]
byteovi = struct.pack('10sid',*L)
print(len(byteovi))
with open("bin1.bin","wb") as f:
f.write(byteovi)
24
Oznaka Pomoću programa |
#include <stdio.h>
typedef struct {
char s[10];
int i;
double d;
} zapis;
int main()
{
zapis z = {"tekst", 10, 0.1};
printf("%lu\n",sizeof(z));
FILE* f = fopen("bin2.bin","wb");
if(!f)return 1;
if( fwrite(&z, sizeof(z), 1, f) != 1 )return 1;
if( fclose(f) != 0 )return 1;
return 0;
}
24
U terminal upišemo |
0000000 74 65 6b 73 74 00 00 00 00 00 00 00 0a 00 00 00
0000010 9a 99 99 99 99 99 b9 3f
0000018
Vidimo da je sadržaj datoteke |
0000000 74 65 6b 73 74 00 00 00 00 00 00 00 0a 00 00 00
0000010 9a 99 99 99 99 99 b9 3f
0000018
|
Učitavanje iz datoteke: import struct
with open("bin1.bin","rb") as f:
byteovi = f.read()
print(struct.unpack('10sid',byteovi))
(b'tekst\x00\x00\x00\x00\x00', 10, 0.1)
|
#include <stdio.h>
typedef struct {
char s[10];
int i;
double d;
} zapis;
int main()
{
zapis z;
FILE* f = fopen("bin2.bin","rb");
if(!f)return 1;
if( fread(&z, sizeof(z), 1, f) != 1 )return 1;
if( fclose(f) != 0 )return 1;
printf("%s; %d; %f\n",z.s, z.i, z.d);
return 0;
}
tekst; 10; 0.100000
|
Homogena polja¶
Python omogućuje i homogena polja tj. ona koja sadrže elemente istog tipa. Prilikom inicijalizacije potrebno je navesti tip podataka za elemente.
>>> from array import array
>>> z = array( 'l', [1, 2, 3, 4, 5] )
>>> print(z)
array('l', [1, 2, 3, 4, 5])
>>> print(z.itemsize)
8
>>> print(len(z))
5
>>> print(len(z.tobytes()))
40
Byteove koje definiraju polje možemo dobiti pomoću from array import array
z = array( 'l', [1, 2, 3, 4, 5] )
with open("bin_array1.bin","wb") as f:
z.tofile(f)
#ili f.write( z.tobytes() )
print(z.itemsize, len(z))
8 5
|
#include <stdio.h>
int main()
{
long z[] = {1, 2, 3, 4, 5};
size_t l = sizeof(z[0]);
size_t N = sizeof(z)/l;
FILE* f = fopen("bin_array2.bin","wb");
if(!f)return 1;
if( fwrite(&z, l, N, f) != N )return 1;
if( fclose(f) != 0 )return 1;
printf( "%lu %lu\n", l, N );
return 0;
}
8 5
|
0000000 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00
0000010 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
0000020 05 00 00 00 00 00 00 00
0000028
|
0000000 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00
0000010 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
0000020 05 00 00 00 00 00 00 00
0000028
Vidimo da su rezultati prethodnih programa isti. |
Byteove koji definiraju elemente polja možemo interpretirati kao elemente i dodati ih u postojeće polje pomoću
from array import array
z = array( 'l' )
with open("bin_array1.bin","rb") as f:
z.fromfile( f, 5 )
#ili z.frombytes( f.read() )
print(z)
array('l', [1, 2, 3, 4, 5])
|
#include <stdio.h>
int main()
{
long z[16];
size_t l = sizeof(z[0]);
size_t N = 5;
FILE* f = fopen("bin_array2.bin","rb");
if(!f)return 1;
if( fread(&z, l, N, f) != N )return 1;
if( fclose(f) != 0 )return 1;
for(int i=0; i<N; i++ )
printf("%ld ", z[i]);
printf("\n");
return 0;
}
1 2 3 4 5
|