Datoteke

Tekstualne datoteke

Primjer koji upisuje neka slova i brojeve u datoteku.

with open("txt1.txt","w") as f:
  print >>f, "1.red: 123", 456
  print >>f, "2.red 1230", 4560.123

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 pa onda 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 float i ispisujemo. Ostatak liste ispisujemo kako jest.

Napomena

Datoteke se zatvaraju u trenutku napuštanja with bloka, tj. nakon izvršenja zadnje naredbe u with bloku.

Binarne datoteke

C interno u memoriji drži samo gole podatke koje je stoga lako direktno prepisati iz memorije u datoteku. Pyhton 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 repr(struct.pack('10s',"tekst"))
'tekst\x00\x00\x00\x00\x00'
>>> print repr(struct.pack('20s',"tekst"))
'tekst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> print repr(struct.pack('i',10))
'\n\x00\x00\x00'
>>> print repr(struct.pack('d',0.1))
'\x9a\x99\x99\x99\x99\x99\xb9?'

Slijedi primjeri koji upisuju i čitaju riječ, int i double u datoteku.

import struct
L=["tekst",10,0.1]
byteovi = struct.pack('10sid',*L)
print len(byteovi)
with open("bin1.bin","wb") as f:
  f.write(byteovi)
24

Oznaka 10sid sastoji se od 10s, i, d. To znači da će se sastaviti struktura u kojoj će string zauzimati 10 byteova nakon kojih slijede int i double. Pri tome se ubacuje isti alignment kao u C-u. Više o oznakama za kodiranje strukture na https://docs.python.org/2/library/struct.html#byte-order-size-and-alignment i na https://docs.python.org/2/library/struct.html#format-characters.

Pomoću programa hexdump možemo vidjeti sadržaj binarnih datoteka. U terminal upišemo hexdump bin1.bin

#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

odnosno hexdump bin2.bin.

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 bin1.bin napravljene iz pythona isti kao datoteke bin2.bin napravljene iz C-a.

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
import struct
with open("bin1.bin","rb") as f:
  byteovi = f.read()
print struct.unpack('10sid',byteovi)
('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